JavaScript正規表現の肯定先読みと否定先読み
時には、このようなタイプの問題を解決する必要があります:
文字列 'aaa' を見つけて '!' に置き換える。
ただし、'aaa' の後に
'x' が続く場合のみ、そして
'x' 自体は置き換えない。
この問題を「力ずく」で解決しようとすると、
うまくいきません:
'aaax baaa'.replace(/aaax/g, '!'); // '! baaa' を返すが、期待するのは '!x baaa'
先読み
この問題を解決するには、'x'
を置き換えるべきではないと伝える方法が必要です。
これは、特別な括弧 (?= )
を使って行われます。この括弧は単に「確認」するだけで、
マッチした部分として「消費」しません。
これらの括弧は肯定先読みと呼ばれます。
肯定 – なぜなら'x'
(このケースでは)が存在しなければならない – その時のみ
置換が起こるからです。
この括弧を使って問題を解決してみましょう:
'aaax aaab'.replace(/aaa(?=x)/g, '!'); // '!x aaab' を返す
否定先読み – (?! ) – も存在します。
これは逆に、何かが存在してはならないと言います。
次の例では、'aaa' の後に
'x' が「ない」場合のみ置換が起こります:
'aaax aaab'.replace(/aaa(?!x)/g, '!'); // 'aaax !b' を返す
後読み
同様に、肯定後読み – (?<= )
が存在します。次の例では、
'aaa' の前に 'x'
がある場合のみ置換が起こります:
'xaaa'.replace(/(?<=x)aaa/g, '!'); // 'x!' を返す
また、否定後読み
– (? も存在します。
次の例では、'aaa' の前に
'x' が「ない」場合のみ置換が起こります:
'baaa'.replace(/(?<!x)aaa/g, '!'); // 'b!' を返す
実践的な問題
関数名を含む文字列が与えられます:
let str = 'func1() func2() func3()';
この文字列から関数名の配列を取得してください。
タグを含む文字列が与えられます:
let str = '<a href="" class="eee" id="zzz">';
このタグの属性名の配列を取得してください。
変数を含む文字列が与えられます:
let str = '$aaa $bbb $ccc xxxx';
ドル記号($)が前に付いている部分文字列を 取得してください。