1

私はこの正規表現を持っています:(?<![A-Z])(?<=[.!?])\s(?=[A-Z]) それは段落を文に分割します(すべての空白に基づいて)。

私はこの段落でそれを使用しました:Did he know that J. Smith is a name? The term is most commonly applied to the placing of a warship in active duty with its country's military forces. The ceremonies involved are Often rooted in centuries old naval tradition. I.D. is a wonderful word.

「J. Smith」で切れるのは、「.」が「.」だと思うからです。文の終わりを表します。

re.split() を使用して配列を出力し、値を改行で区切ります

これは、上記の段落からの出力です。

Did he know that J.
Smith is a name?
The term is most commonly applied to the placing of a warship in active duty with its
country's military forces. (no newline at beginning of sentence)
The ceremonies involved are Often rooted in centuries old naval tradition.
I.D. is a wonderful word.`

「ID」では機能しますが、「J. Smith」では機能しないのはなぜですか? 論理的には...

文字列でこの構造を検出したい:

大文字なし+ピリオド/?/!+空白+大文字

4

2 に答える 2

4

後読み (または先読み) は、ゼロ幅のアサーションです。つまり、アサーションが true である任意のポイントで、長さゼロの文字列に一致します。

特に、これは、正規表現に 2 つの連続した後読み (または先読み) アサーションがある場合、両方が同じポイントで一致する場合にのみ一致することを意味します。

したがって、(?<![A-Z])(?<=[.!?])前の文字が範囲内の大文字ではなく、文字の1 つである場合A-Z .!?一致します。明らかに、後者のアサーションは前者を暗示しているため、(?<![A-Z])正規表現の一部は実際の効果はありません。

あなたが主張したい.!?のは、前の文字がのであり、その前の文字が大文字ではないということです。もしそうなら、1つの解決策はに置き換えること(?<![A-Z])です(?<![A-Z].)


Ps。元の正規表現が分割されない理由 " I.D. is" は、一致する最初のドットの後に\sスペースがなく、2 番目のピリオドの後のスペースの後に先読みアサーションで必要な大文字が続いていないためです。

于 2012-12-28T02:27:01.760 に答える
3

@unutbuのポイントは別として、同じ文字で両方の後読みをアサートしているため、期待どおりに動作しない可能性があります。つまり、「前の文字は ではなく[A-Z]です [.!?]。」多分あなたはそれらを入れ子にするつもりです、例えば

(?<=(?<![A-Z])[.!?])\s(?=[A-Z])
于 2012-12-28T02:26:51.687 に答える