正規表現のエスケープと u フラグ
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ u フラグをつけると エスケープ不要な記号をエスケープするとエラーにされる
◆ - は [] の中のみエスケープが必要になる
◆ 正規表現内でも埋め込み場所でエスケープ処理を分けないといけない
◆ すごく不便になった
◆ \ をつけるのではなく \xXX 形式にすればエスケープエラーにされない
◆ - は [] の中のみエスケープが必要になる
◆ 正規表現内でも埋め込み場所でエスケープ処理を分けないといけない
◆ すごく不便になった
◆ \ をつけるのではなく \xXX 形式にすればエスケープエラーにされない
エスケープ機能がない
JavaScript は色々機能が増えてきてるのに未だに正規表現と HTML の文字列エスケープ機能がありません正規表現のエスケープで調べて出てくるのは相変わらず昔からの Stackoverflow のページです
https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
こういう 置換を使って正規表現で特別な意味を持つ記号の前に 「\」 を追加する方法です
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
escapeRegex(".")
// \.
escapeRegex("+")
// \+
escapeRegex("!")
// !
u フラグをつけるとエスケープルールまで変わる
毎回エスケープ関数を持ってくる手間はありますが それだけで済んでいましたしかし u フラグがあると新たな問題が起きます
u フラグ自体は Unicode に対応するもので 4 バイト文字の絵文字もサポートしたいなら必要です
"🚀".length
// 2
"🚀".match(/./u)
// ["🚀", index: 0, input: "🚀", groups: undefined]
"🚀".match(/./)
// ["\ud83d", index: 0, input: "🚀", groups: undefined]
u フラグありで - をエスケープするとエラーが起きます
new RegExp("\\-", "u")
// Uncaught SyntaxError: Invalid regular expression: /\-/: Invalid escape
- が特別な意味を持つのは [] の内側のみで それ以外の場所ではエスケープが不要だからのようです
エスケープが不要な ! をエスケープしても同様のエラーです
new RegExp("\\!", "u")
// Uncaught SyntaxError: Invalid regular expression: /\!/: Invalid escape
u フラグをつけなければ 不要なエスケープがあっても問題なく動いていました
"!-".match(new RegExp("\\!\\-"))
// ["!-", index: 0, input: "!-", groups: undefined]
これまで対応できてたのなら 不要なエスケープも許容して無視してほしいです
u フラグの有無でエスケープを変えるのは面倒です
なぜか / はエスケープがあってもなくても良いようでした
正規表現リテラルなら / で囲むのでエスケープが必要ですが RegExp コンストラクタを使って文字列とするならエスケープ不要だと思うのですけど
new RegExp("/").source === new RegExp("\\/").source
// true
new RegExp("/", "u").source === new RegExp("\\/", "u").source
// true
エラーは出ずに source は一緒になってます
「-」 は場所によってエスケープが必要になる
単にエスケープ不要なものはエスケープしてはいけないというだけなら まだ良いのですが - は場所によって必要かどうかが変わりますnew RegExp(regexp_source, "u")
new RegExp(`[${regexp_source}]`, "u")
下側のように [] の中で使う場合はエスケープしないといけません
使う場所によってエスケープ関数の使い分けが必要になります
こういうタグ関数で埋め込み場所のコンテキストを理解してエスケープを切り替えてくれるのが欲しくなります
regexp`^foo/${bar}/[${baz}]$`
ですが そもそも u フラグで余計な変更をしなければこんなことも不要だったんですよね
なんでこんな余計なことをしたんでしょうか
場所によってエスケープの必要不要が変わるものまで厳格化したら面倒になるなんて普通にわかってると思うのですけど
ベストアンサー
記号に 「\」 をつけるタイプのエスケープだからこうなるのであって 「\xXX」 形式にすれば Invalid escape なんて言われませんfunction escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, c => "\\x" + c.charCodeAt().toString(16))
}
escapeRegex("!")
// !
escapeRegex("/")
// \x2f
escapeRegex("-")
// \x2d
常にエスケープできるので [] の内外を気にせずエスケープできます
"a-b".match(new RegExp("a\\x2db", "ug"))
// ["a-b"]
"a-b".match(new RegExp("[a\\x2db]", "ug"))
// (3) ["a", "-", "b"]
以前 どの記号とか考えるのが面倒で全部の文字列を \uXXXX 形式にしたことがあります
当時は u フラグのこの問題を気にしてませんでしたが 割と正しかったんですね