【问题标题】:C# System.RegEx matches LF when it should notC# System.RegEx 在不应该匹配 LF 时匹配
【发布时间】:2021-11-06 01:40:42
【问题描述】:

以下返回真

Regex.IsMatch("FooBar\n", "^([A-Z]([a-z][A-Z]?)+)$");

也是这样

Regex.IsMatch("FooBar\n", "^[A-Z]([a-z][A-Z]?)+$");

RegEx 默认处于 SingleLine 模式,因此 $ 不应匹配 \n。 \n 不是允许的字符。

这是为了匹配单个 ASCII PascalCaseWord(是的,它将匹配尾随大写)

不适用于 RegexOptions.Multiline | 的任何组合正则表达式选项.单行

我做错了什么?

【问题讨论】:

  • 在 Windows 上,换行符是 \r\n,而不是 \n。
  • 是的,但 .NET 的 RegEx 实现与之匹配。出于某种奇怪的原因,请查看文档。
  • 是的,你是对的,它将 \n 视为换行符,因此正则表达式仅检查“FooBar”,这就是它匹配的原因。不知道为什么它将 \n 视为新行,可能是为了增加与其他操作系统的兼容性...
  • 不应该。正则表达式选项。多行字段命名空间:System.Text.RegularExpressions 程序集:System.Text.RegularExpressions.dll、System.dll、netstandard.dll 多行模式。更改 ^ 和 $ 的含义,使其分别匹配任何行的开头和结尾,而不仅仅是整个字符串的开头和结尾。有关详细信息,请参阅正则表达式选项主题中的“多行模式”部分。

标签: c# .net regex


【解决方案1】:

在 .NET 正则表达式中,$ 锚点(与 PCRE、Python、PCRE、Perl 中一样,但 不是 JavaScript)匹配行尾,或 最后一行之前的位置字符串中的换行符 ("\n").

this documentation:

$   匹配必须出现在字符串或行的末尾,或者在字符串或行的末尾\n之前。如需更多信息,请参阅End of String or Line

没有修饰符可以在 .NET 正则表达式中重新定义它(在 PCRE 中,您可以使用 DPCRE_DOLLAR_ENDONLY 修饰符)。

你一定是在寻找\z锚点:它只匹配字符串的最后

\z   匹配只能出现在字符串的末尾。如需更多信息,请参阅End of String Only

short test in C#:

Console.WriteLine(Regex.IsMatch("FooBar\n", @"^[A-Z]([a-z][A-Z]?)+$"));  // => True
Console.WriteLine(Regex.IsMatch("FooBar\n", @"^[A-Z]([a-z][A-Z]?)+\z")); // => False

【讨论】:

  • 请投票给这个答案。当我发布我的答案时,我没有看到这一点。再次感谢维克托
【解决方案2】:

来自维基百科:

$ 匹配字符串的结束位置或字符串结束换行符之前的位置。在基于行的工具中,它匹配任何行的结束位置。

所以你问的是在字符串的开头之后是否有一个大写字母,后跟任意次数(零或一个字母),然后是字符串的结尾,或者就在前面的位置新队。

这一切似乎都是真的。

是的,不同的文档来源之间似乎存在一些不匹配,关于什么被认为是 newline 以及 $ 如何工作或应该如何工作。它总是让人想起智慧:

有时一个人有一个问题,他认为他会使用正则表达式来解决它。
现在这个人有两个问题。

【讨论】:

  • 不,不应该,在 WIndows 上新行必须是 \r\n,而不是 \n,所以行上的最后一个字符是 \n
  • @Gusman Regex.IsMatch("FooBar\n\n", "^[A-Z]([a-z][A-Z]?)+$", RegexOptions.Singleline)(两个换行符)返回 false。使用 MultiLine,它返回 true。我认为他是对的。 IIRC 将普通的 '\n' 视为换行符,以便与 UNIX 兼容,这是 MS 领域的一个古老约定。在 C 语言中,您会将\n 写入以文本模式打开的FILE *,它实际上会将\r\n 写入文件。在文件中是\r\n,但在缓冲区中可能是\n
  • @EdPlunkett 是的,他是对的,但不应该是对的,这就是我的意思 XD。问题是“新行”的定义,在 Windows 上,“新行”是 CR+LF,但正则表达式将 LF 视为“新行”,就像在 *nix 上一样
  • @Gusman Au contraire: "_read 返回读取的字节数,如果文件中剩余的字节数少于 count 或 如果文件中剩余的字节数可能小于 count以文本模式打开,在这种情况下,每个回车换行 (CR-LF) 对都将替换为单个换行符。” 缓冲也是如此IO 函数。
  • @EdPlunkett:见MS DOTNET regex documenation about anchors。不容易找到,但行为记录在案。
猜你喜欢
  • 2021-04-26
  • 2021-08-26
  • 2011-04-08
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 2019-12-07
相关资源
最近更新 更多