4

JavaScriptと正規表現を使用して一連のキーワードを強調表示しようとしていますが、1つの問題に直面しています。キーワードには、@ text #numberなどのリテラル文字と特殊文字が含まれている可能性があります。単語境界を使用して、単語全体を照合および置換しています。部分的な単語(別の単語に含まれる)。

var pattern = new regex('\b '( + keyword +')\b',gi);

ここで、この式はキーワード全体に一致し、それらを強調表示しますが、「number:」などのキーワードが強調表示されない場合に備えて。

\bword\b単語の境界と特殊文字の一致は英数字以外の文字であるため、上記の式とは一致しないことを認識しています。上記を実現するために使用できる正規表現を教えてください。

==更新==

上記については、以下の正規表現に対するTimPietzckerの提案を試しました。

expr: (?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)

上記は、英数字と英数字以外の文字を含む単語全体を一致させるために機能しているようですが、キーワードの前後にスペースのない連続したhtmlタグがある場合は常に、そのキーワードは強調表示されません(例:ソーシャルセキュリティ*番号: <br> *)次の正規表現を試しましたが、キーワードの前にあるhtmlタグが置き換えられています

expr: (?:^|\b|\s|<[^>]+>)number:(?:$|\b|\s|<[^>]+>) 

ここでキーワード番号について:(ブラウザが< br >タグを解釈するのを避けるためにbrタグのために意図的にスペースを追加しました)間にスペースを入れずに次に来るものは、キーワードで強調表示されます。

英数字と英数字以外の文字の両方を含む単語全体の連続するhtmlタグを無視する式を提案できますか。

4

6 に答える 6

2

2021 更新: JS は後読みをサポートするようになったため、この回答は少し古くなっています。

2 つの問題があります。JavaScript は後読みをサポートしておらず\b、英数字と英数字以外の文字の境界しか検出しません。

最初の質問:キーワードの単語境界を正確に構成するものは何ですか? 私の推測では、\b境界または空白のいずれかでなければなりません。その場合は、検索できます

"(?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)"

もちろん、キーワードの周りの空白文字@number#も一致の一部になりますが、おそらくそれらを強調表示することはそれほど問題ではありません. それ以外の場合、つまり一致する可能性のある実際の単語境界がある場合、スペースは一致の一部にならないため、ほとんどの場合は正常に機能するはずです。

関心のある実際の単語は後方参照 #1 にあるため、それを個別に強調表示できればさらに効果的です。

編集: スペース以外の文字がキーワードの前後に発生する可能性がある場合、(JavaScript で立ち往生している場合) できる唯一のことは次のとおりです。

  1. キーワードが alnum 文字で始まっているかどうかを確認してください。
  2. その場合\bは、正規表現の先頭に追加してください。
  3. キーワードが alnum 文字で終わっているかどうかを確認します。
  4. \bその場合は、正規表現に追加してください。

したがって、 には;keywordを使用します。\bkeyword\bのためnumber:に、使用し\bnumber:ます。のため@twitterに、使用して@twitter\bください。

于 2010-11-18T12:00:14.090 に答える
1

両側に空白文字がある部分文字列を探す必要があります。JavaScript が後読みをサポートしている場合、これは次のようになります。

var re = new RegExp('(?<!\\S)' + keyword + '(?!\\S)', 'gi');

ただし、それは機能しません (ただし、Perl やその他のスクリプト言語では機能します)。代わりに、先頭の空白文字(または文字列の先頭) を一致の先頭部分として含める必要があります (オプションで、実際に探しているものを $1 にキャプチャします)。

var re = new RegExp('(?:^|\\s)(' + keyword + ')(?!\\S)', 'gi');

一致が始まる実際の場所は、 によって返されるプロパティによって返されるものの1 文字後になること、および一致した文字列にアクセスしている場合は、最初の文字を で削除するか、単にキャプチャされたものにアクセスする必要があることを考慮してください。.indexre.exec(string).slice(1)

于 2010-11-18T11:58:40.577 に答える
0

多分あなたがやろうとしていることは

'\b\W*(' + keyword + ')\W*\b'
于 2010-11-18T11:33:58.493 に答える
0

先読みと後読みがあなたの答えです:"(?=<[\s^])" + keyword + "(?=[\s$])"。角かっこ内のビットは一致に含まれないため、キーワードで許可されていない文字をすべて含めてください。

于 2010-11-18T11:35:04.693 に答える
0

これを試してみてください...

var pattern = new regex(@"\b"+Regex.escape(keyword)+@"\b",gi);
于 2011-09-09T20:31:46.427 に答える
0

ティムが正しく指摘して\bいるように、人々がよく考える方法とは異なる働きをするトリッキーなことです。この問題の詳細と、それに対してできることについては、この回答をお読みください。

簡単に言えば、これは左への境界です。

(?(?=\w)(?<!\w)|(?<!\W))

これは右側の境界です。

(?(?<=\w)(?!\w)|(?!\W))

人々は常にスペースが関係していると考えていますが、そうではありません。ただし、実際の定義がわかったので、それを簡単に組み込むことができます。上記の 2 つのパターンで、and\w\W交換 して交換することができます。または、else ブロックに空白の認識を追加することもできます。\s\S

于 2010-11-18T13:58:15.480 に答える