C#のRegex.Splitを使用して、単語間の区切り文字を見つける正規表現があります。
[\b\s\p{P}]+
「サンプルテキスト。another:word」では、機能し、次のように生成されます。テキスト| 別の| ワード。素晴らしい!
「単語120,000別の単語」でそれは生成します:単語| 120 | 000 | 別の| ワード。良くない!
数字の中のコンマが一致しないように正規表現を変更するにはどうすればよいですか?つまり、120,000が壊れないように?
でこれを行うことはRegex.Split
、追加の要件が出現するにつれて、より複雑になるだけであることがわかると思います。逆を行う代わりに使用する方が望ましい場合がありますRegex.Match
(論理的な「単語の境界」ではなく「単語全体」を認識します)。
理由は次のとおりです。
((?<=\p{L})\p{P}(?=\p{L}))|(\p{Z}|(?<=[\p{Z}\p{P}])\p{P}|\p{P}(?=[\p{Z}\p{P}]))+
かわいくないので、説明しましょう。\s
まず、クラス(表示/非表示の空白)に置き換えました\p{Z}
。理由はありません。次に、この正規表現は4つの異なるものに一致します。
(?<=\p{L})\p{P}(?=\p{L})
これは、文字の間に挟まれた句読文字と一致します。に一致する必要が:
ありanother:word
ます。これは、数量詞が適用されない唯一のサブパターンでもあり+
ます(意味がありません)。ポジティブルックアラウンドは、文字の存在を主張するために使用されますが、それらの一致は避けます。
\p{Z}
これは空白のシーケンスと一致します。このようなシーケンスはすべて分割されます。
(?<=[\p{Z}\p{P}])\p{P}
これは、句読点または空白以外の文字の前にある句読文字と一致し、前向きな後読みを使用します。
\p{P}(?=[\p{Z}\p{P}])
これは上記の逆です。句読文字の後に句読点または空白以外のものが続くものと一致します。
したがって、のコンマ100,000
は上記のいずれにも一致しないため、この正規表現はそのトークンを分割しません。しかし、これがどこに向かっているのかがわかります。1つのトークンとしてまとめたいRegex.Split
シンボルを指定する代わりに、使用する場合は他のすべてを指定する必要があります。
これを試してください:
(([\s\p{P}](?!\d))|((?<!\d)[\s\p{P}]))+
前半
([\s\p{P}](?!\d))
数字が続かない区切り文字と2番目の区切り文字(数字が続かない区切り文字)に一致します。