如果我想找到段落末尾的所有句号,我可以\.($|\n)
。但是,我怎么能否定这一点,然后说出一个句号,其后是任何一个ISN' T中的一个,因为元字符不能在字符类中工作,这会阻止我使用否定的字符类? / p>
答案 0 :(得分:5)
$
中的内容是什么?这取决于!
答案很大程度上取决于您使用的语言和正则表达式引擎。你看,
$
断言我们位于字符串的末尾,或者在字符串末尾的任何回车符或换行符之前。因此,使用\.(?!$)
$
断言我们位于字符串的末尾或字符串末尾的任何换行符之前。所以你可以使用\.(?!$|\r)
$
断言我们位于字符串的末尾。因此,您需要使用\.(?!$|[\r\n])
因此,对于多引擎解决方案,最安全的是:
\.(?!$|[\r\n])
但在正确的背景下,其他两个选项是完全可以接受的。
<强>解释强>
\.
与文字句点匹配(?!$|[\r\n])
断言后面的内容既不是“字符串的结尾”,也不是回车或换行符。答案 1 :(得分:4)
使用Negative Lookahead执行此操作。
\.(?!\n|$)
<强>解释强>:
\. '.'
(?! look ahead to see if there is not:
\n '\n' (newline)
| OR
$ before an optional \n, and the end of the string
) end of look-ahead
答案 2 :(得分:4)
最有用的速记版本的负面向前EOL检查在这段时间结束后使你的整个模式像这样:
(?x: # enable comments
\. # a literal dot character
(?! # look ahead for not the following{
\R ? # optional EOL grapheme cluster
\z # at the true end of string
) # } end look ahead
)
假设您不希望它与“interstitially”匹配(即,在任何行终止符字形之前),这将更简单:
(?=\R)
可以对\R?
作为\R*
进行一些论证,以防万一你碰巧在记录的末尾有多个换行符,比如行中的几个换行符。那样,在字符串结束之前允许使用0,1,2或多个EOL字形。
另一方面,很可能一个段落必须至少有两个EOL字素,而不仅仅是一个。例如,在此处的标记和其他具有“空行分隔”类型的段落的文件中都是如此。所以没有EOL可以,两个或更多也是,但不只是其中之一。
对于这样的文本,你需要\R{2,}
,但整个位都是可选的,在这种情况下会产生:
(?x: # enable comments
\. # a literal dot character
(?! # look ahead for NOT the following {
(?:
\R {2,} # two or more EOL grapheme clusters
) ? # # optionally
\z # at the true end of string
) # } end negated look ahead
)
如果你的正则表达式中没有来自UTS 18: Unicode Regular Expressions — Line Boundaries的\R
,那么你必须用艰难的方式写出来,这很烦人:
(?x: # We are emulating \R per UTS#18
(?> # Prohibit backtrack within subpattern
\r \n # Match a CRLF without backtracking
# or else any code point with the
# vertical space character property
# \p{VertSpace}, here enumerated in full
| [\x0A-\x0D\x85\x{2028}\x{2029}]
)
)
你需要no-backtracking位来避免允许\R{2}
匹配单个CRLF,并且不允许这样做。
最后要考虑的是,是否要允许可选的水平空格介入期间和EOL之间。我宁愿想象你这么做,但是如果没有更严格的正式规范,就不可能这么说。
答案 3 :(得分:2)