【JavaScript, 正規表現】ある形式で囲まれたもの以外の文字列を置換する


以下の正規表現は間違っているかもしれません。

十分テストした上で実用してください。

間違いに気づいた方は、どうかご連絡くださいm(_ _)m


【実験ページ】
http://usamimi.info/~sutara/sample/regexp_02.html


"てすと"を"test"に置換します。
ただし、class名が"dumy"のタグで囲まれたものは除外します。


例えば下記の文字列を


これはてすと<span class="dumy">てすと</span>てすとですよ<span class="dumy">てすと</span>
下記のように変換したい場合。

これはtest<span class="dumy">てすと</span>testですよ<span class="dumy">てすと</span>


コールバック関数付きのreplaceを使います。
下記は、除外するパターンが明確に決まっている場合の、最も単純な例です。


var after = before.replace(
/(てすと)|(<span class="dumy">てすと<\/span>)/g,
function() {
if (arguments[2]) {
return arguments[2];
} else if (arguments[1]) {
return 'test';
}
}
);
除外パターンに一致した場合は置換せずにそのまま返し、
それ以外に残った"てすと"のみを"test"に置換しています。


次は、かなり複雑です。
class名が"dumy"のタグに囲まれている"てすと"なら、全て除外します。


var after = before.replace(
/(てすと)|(<(?:(?!\sclass="|>).)+\sclass="(?:(?:(?!dumy|")\w)+\s)*dumy(?:\s\w+)*"[^>]*>(?:(?!てすと|<).)*てすと[^<]*<\/[^>]+>)/g,
function() {
if (arguments[2]) {
return arguments[2];
} else if (arguments[1]) {
return 'test';
}
}
);
コールバック関数の部分は変わらないので、正規表現の、

<(?:(?!\sclass="|>).)+\sclass="(?:(?:(?!dumy|")\w)+\s)*dumy(?:\s\w+)*"[^>]*>(?:(?!てすと|<).)*てすと[^<]*<\/[^>]+>
の部分のみを解説します。
前提知識として…、
"\s"は、空白文字です。(\r\n\s\t)
"\w"は、アルファベットと数字とアンダーバーです。([a-zA-Z0-9_])
"(?:"は、"パターンをグループ化したいけど、キャプチャはしたくない"という場合の記法です。
"(?!"は否定先読みです。


【参考】
れぶろぐ - [regexp] ある文字列を含まないものにマッチする正規表現
http://www.revulo.com/blog/20080415.html


では、解説します。

<
HTMLタグの始まりにマッチします。以下はタグ内の文字列ということになります。
(?:(?!\sclass="|>).)+
『(空白)class="』かHTMLタグの終わり以外の、文字と空白にマッチします。
"h1"や"span"などのタグ名や、他の属性名などを消化することを想定しています。
\sclass="
これ以降は、クラス名に対して検査を行います。
(?:(?:(?!dumy|")\w)+\s)*
"dumy"まはた『"』ではなく、末尾に空白が付く、
というパターンがあればそれを消化します。
dumy以外のクラス名が併記されている場合を想定しています。
※『class="hoge dumy"』など。
dumy
当然、クラス名に"dumy"が含まれていなければなりません。
(?:\s\w+)*
その他クラス名が併記されていれば消化します。
※『class="dumy fuga"』など。
"
クラス名はここで終了します。
[^>]*
HTMLタグ終了まで、他に何か属性名などがあれば消化します。
>
HTMLタグはここで終了です。
(?:(?!てすと|<).)*
"てすと"またはHTMLタグ開始の記号以外の、文字列があれば消化します。
てすと
当然、置換対象の"てすと"は必ず含まれていなければなりません。
[^<]*
閉じタグの開始までの文字列を消化します。
<\/
閉じタグが始まります。
[^>]+
閉じタグが終了するまでの文字列を消化します。
>
閉じタグが終了します。
これで、除外パターンの記述が完了しました。