はじめに
仕様くん 「下のファイルから color: xxx; の部分だけ抜いといて〜」
私 「...(なんか難しそう)」
仕様くん 「でも<style>...</style>
の中からは抜いちゃダメだよ」
私 「...(絶望)」
※わかりやすくするためにhtml形式で書いてますが、用意されていたのはテキストファイル形式でした。
<h1 style="color:blue">あいうえお</h1>
<p style="font-weight:600; font-size:14px;"><a style="color:red;">かきくけこ</a></p>
<style>
h1, p, a {
color: #fff;
}
</style>
実装
// 引数でテキストファイル受け取り
function(str) {
// テキストファイル内で「<style>」が何文字目に出るかを保持
let startIndex = str.indexOf("<style>");
// テキストファイル内の<style>以降を保持
let styleDoc = str.slice(startIndex);
// 「color: xxx;」をテキスト内で空文字置換
let removeColorDoc = str.replace(/(?<!-)color:(.*?);/g, '');
// 置換したファイルから、<style>より前を取得
let removeColorHtmlDoc = removeColorDoc.slice(0 , startIndex - 1);
// 置換したファイルの<style>より前部分と、元ファイルの<style>移行を合体
let removeColorStyleDoc = removeColorHtmlDoc + styleDoc;
}
正規表現の中身
// 「color: xxx;」をテキスト内で空文字置換
let removeColorDoc = str.replace(/(?<!-)color:(.*?);/g, '');
否定的先読み
(?<!-)color
は、否定的先読みという手法で、例えばbackground-color:
は引っ掛けず、color:
だけを引っ掛けようとしています。
gオプション
末尾のg
はgオプションというものです。通常replace
を使うと、対象の文字列がいくつあっても最初にマッチした文字列しか置換できません。gオプションを使うと、その縛りが解消され、全てのcolor: xxx;
を置き換えてくれます。
結果
<style>
より前部分から、color:xxx;
の表記が消えました!!
めでたい。
<h1 style="">あいうえお</h1>
<p style="font-weight:600; font-size:14px;"><a style="">かきくけこ</a></p>
<style>
h1, p, a {
color: #fff;
}
</style>
この例に沿って書くと、例えば color: transparent;
なども全て消し飛びます。「色変更は消したいけどtransparentは残したい」などの要望の場合、現状のJavascriptでは難しそうです。
終わりに
正規表現、なかなか使いこなせるようになれませんが、良い勉強になりました。