C# - 负先行似乎不起作用

C# - Negative Lookahead doesn't seem to work

正在使用 C# .Net 4.5

我需要一个表达式来查看字符串并在字符串中的任何位置有两个或更多大写字符时匹配失败。

我认为正确的模式应该是这样的:

(?![A-Z]{2,})\w

注意:?!?<!

都试过了

我得到了相反的结果,搜索一个字符串,return 如果连续有 2 个或更多的大写字母并且模式如下:

为真
(?=[A-Z]{2,})\w

但是我必须让这个工作脱离负先行模式。

从我读过的所有帖子来看,这应该是正确的方法,但它对我不起作用。

我已通读以下问题:

C# regexp negative lookahead 要么 Regex negative lookahead in c#

等...

我不想一一列举。但是他们说的都差不多,就是用负前瞻(?!)

谁能看出我做错了什么导致它不起作用?

编辑:

添加了一些示例:

  1. 你好 - 应该通过
  2. 你好 - 应该失败
  3. heLLo - 应该会失败
  4. 你好 - 应该会失败

进阶版:

  1. Hello World - 应该通过
  2. Hello WOrld - 应该会失败
  3. 你好世界 - 应该会失败
  4. 你好世界 - 应该失败

如果您要匹配某些东西,您只需要匹配失败即可。

你试图匹配的是失败。

如果 [A-Z].*?[A-Z] 匹配包含 2 个大写字母的字符串。

如果不是连续两个,就是这个 (multi-line) -> ^[^A-Z\r\n]*(?:[A-Z](?![A-Z])[^A-Z\r\n]*)*$

要匹配 non-empty 字符串,只需添加一个简单的断言。

^(?!$)[^A-Z\r\n]*(?:[A-Z](?![A-Z])[^A-Z\r\n]*)*$

对于 Unicode 属性,使用 \p{Lu} 形式

^[^\p{Lu}\r\n]*(?:\p{Lu}(?!\p{Lu})[^\p{Lu}\r\n]*)*$


输入:

1.Hello - Should pass
2.HEllo - Should fail
3.heLLo - Should fail
4.HELLO - should fail

Advanced version:
1.Hello World - should pass
2.Hello WOrld - should fail
3.hello wORld - should fail
4.hello WORLD - should fail

基准

Regex1:   ^(?!.*\b\w*\p{Lu}\w*\p{Lu}).*$
Options:  < ICU - m >
Completed iterations:   80  /  80     ( x 1000 )
Matches found per iteration:   5
Elapsed Time:    8.28 s,   8279.28 ms,   8279281 µs


Regex2:   ^[^\p{Lu}\r\n]*(?:\p{Lu}(?!\p{Lu})[^\p{Lu}\r\n]*)*$
Options:  < ICU - m >
Completed iterations:   80  /  80     ( x 1000 )
Matches found per iteration:   5
Elapsed Time:    3.88 s,   3875.04 ms,   3875039 µs

您可以使用以下正则表达式:

^(?!.*\b\w*\p{Lu}\w*\p{Lu}).*$

regex demo

它也将匹配空字符串,但您可以使用 + 量词而不是 * 来要求至少 1 个字符。

要使用此模式匹配换行符,您需要使用 RegexOptions.Singleline 修饰符。

一旦发现以零个或多个单词字符开头、后跟大写字母、再后跟零个或多个单词的单词,锚定在字符串开头的否定前瞻 (?!.*\b\w*\p{Lu}\w*\p{Lu}) 将无法匹配单词字符,然后又是一个大写字母。您可以使用限制量词将其缩短:^(?!.*\b(?:\w*\p{Lu}){2}).*$.