0

バックグラウンド

テキスト内の特定の単語を何度も何度も見つけなければならないシナリオがあります。私は現在、このような形式の一連の正規表現を使用しています...

"((^)|(\W))(?<c>Word1)((\W)|($))"

"((^)|(\W))(?<c>NextWord)((\W)|($))"

"((^)|(\W))(?<c>AnotherWord)((\W)|($))"

..。

この正規表現オブジェクトのリストは、データのチャンクでループされ、一致が抽出されます(1回のregex.matches(data)呼び出しに対して1回のループ)

事前にコンパイルするなど、最適化するためにできる限りのことをしました。

ただし、リストは長くなり、プロセスを最適化するために、より大きなコンパイル済み正規表現の作成を開始することにしました。そのような...

"((^)|(\W))(?<c>((Word1)|(NextWord)|(AnotherWord)))((\W)|($))"

これにより、速度が大幅に低下しますが、修正方法がわからないという副作用があります。

単語がデータ内に並んでいる場合(スペースで区切られている場合、たとえば「Word1 NextWord AnotherWord」)、「Word1」の正規表現には末尾のスペースも含まれているため、2番目の単語はキャプチャで失われます。「NextWord」で発生する可能性のある一致は、前の一致の一部であるため、先頭のスペースがなくなりました。

質問

誰でもこの正規表現を変更できますか(.net形式)

Pattern = "((^)|(\W))(?<c>((Word1)|(NextWord)|(AnotherWord)))((\W)|($))"

「.matches(data)」を1回呼び出すだけで、以下のリストにあるすべての単語をキャプチャできます。

data = "Word1 NextWord AnotherWord" 

?(効率の向上を犠牲にすることなく)

結果

私がこれについて言及しようと思っただけです。提案された回答/修正を先読みと後読みで適用した後、使用方法がわかりました:)、変更したコードの速度が347倍(以前のテスト速度の0.00347%)向上しました。これは、複数の式に入るときに間違いなく覚えておくべきことです。とても幸せです。

4

2 に答える 2

1

\b記号を使用してください。これは、単語/非単語の境界で一致します。

\b(?((Word1)|(NextWord)|(AnotherWord)))\b
于 2012-10-17T01:41:44.823 に答える
1

境界チェックまたは先読み/後読みのいずれかを使用して、一致が空白を消費せずにチェックするようにすることができます。

そのようです:

Pattern = @"\b(Word1|NextWord|AnotherWord)\b"

または、後読みと先読みを使用します。

Pattern = @"(?<=\W|^)(Word1|NextWord|AnotherWord)(?=\W|$)"
于 2012-10-17T01:43:00.670 に答える