使用 C# 的 Regex.Split,我有一个正则表达式,可以找到单词之间的分隔符:
[\b\s\p{P}]+
在“示例文本。另一个:单词”上,它可以工作,并产生:示例| 正文| 另一个| 词。伟大的!
在“单词 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}
类(可见/不可见空格)替换了,因为为什么不呢。其次,这个正则表达式匹配四个不同的东西:
(?<=\p{L})\p{P}(?=\p{L})
这匹配夹在字母之间的标点符号。需要匹配:
in another:word
。这也是+
量词不适用的唯一子模式(这没有任何意义)。正向环视用于断言字母的存在,但避免匹配它们。
\p{Z}
这匹配一系列空白。所有这些序列都会导致分裂。
(?<=[\p{Z}\p{P}])\p{P}
这匹配一个标点符号,该标点符号前面有除标点符号或空格以外的任何内容,使用正向向后查找。
\p{P}(?=[\p{Z}\p{P}])
这与上面的相反:它匹配一个标点字符,后跟标点符号或空格以外的任何内容。
因此,由于逗号100,000
与上述任何一个都不匹配,因此该正则表达式不会拆分该令牌。但是您可以看到这是怎么回事:与其指定要作为一个标记保持在一起的符号,不如使用Regex.Split
您必须指定...其他所有内容。
试试这个:
(([\s\p{P}](?!\d))|((?<!\d)[\s\p{P}]))+
上半场
([\s\p{P}](?!\d))
匹配任何不跟随数字的分隔符和第二个 - 任何分隔符,不跟随数字。