c# - 为什么 ^*$ 匹配 "127.0.0.1"

标签 c# regex

我不明白,为什么会出现下面的正则表达式:

^*$

匹配字符串“127.0.0.1”?使用 Regex.IsMatch("127.0.0.1", "^*$");

使用 Expresso,它不匹配,这也是我所期望的。使用表达式 ^.*$ 确实匹配字符串,这也是我所期望的。

从技术上讲,^*$ 应该匹配字符串/行的开头任意多次,然后是字符串/行的结尾。似乎 * 被隐含地视为 .*

我错过了什么?

编辑: 运行以下命令以查看问题示例。

using System;
using System.Text.RegularExpressions;

namespace RegexFubar
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Regex.IsMatch("127.0.0.1", "^*$"));
            Console.Read();
        }
    }
}

我不希望 ^*$ 匹配我的字符串,我想知道为什么它确实匹配它。我认为表达式应该导致抛出异常,或者至少是不匹配。

编辑2: 消除任何困惑。我写这个正则表达式并不是为了让它匹配“127.0.0.1”。我们的应用程序的用户输入了表达式,并想知道为什么它在不应该匹配字符串的情况下匹配。在查看它之后,我无法解释为什么它匹配 - 特别是因为 Expresso 和 .NET 似乎以不同的方式处理它。

我猜这个问题的答案是由于 .NET 实现避免抛出异常,甚至认为它在技术上是一个不正确的表达式。但这真的是我们想要的吗?

最佳答案

嗯,理论上你是对的,应该不匹配。但这取决于内部实现的工作方式。大多数正则表达式。将采用您的正则表达式并从前面去除 ^ (注意它必须从字符串的开头匹配)并从末尾去除 $ (注意它必须到字符串的末尾),剩下的只是“* "和 "*"本身就是一个有效的正则表达式。您正在使用的实现在如何处理它方面是错误的。您可以尝试将“^*$”替换为“*”会发生什么;我想它也会匹配一切。该实现似乎将单个星号视为“.*”。

根据 ISO/IEC 9945-2:1993 标准,POSIX standard 中也对此进行了描述, 它被打破。它被打破是因为标准说在 ^ 字符之后,星号根本没有特殊含义。这意味着“^*$”实际上应该只匹配一个字符串,这个字符串是“*”!

引用标准:

The asterisk is special except when used:

  • in a bracket expression
  • as the first character of an entire BRE (after an initial ^, if any)
  • as the first character of a subexpression (after an initial ^, if any); see BREs Matching Multiple Characters .

因此,如果它是第一个字符(如果存在 ^,则不算作第一个字符)它没有特殊含义。这意味着在这种情况下,一个星号应该只匹配一个字符,那就是一个星号。


更新

微软说

Microsoft .NET Framework regular expressions incorporate the most popular features of other regular expression implementations such as those in Perl and awk. Designed to be compatible with Perl 5 regular expressions, .NET Framework regular expressions include features not yet seen in other implementations, such as right-to-left matching and on-the-fly compilation.

来源:http://msdn.microsoft.com/en-us/library/hs600312.aspx

好吧,让我们来测试一下:

# echo -n 127.0.0.1 | perl -n -e 'print (($_ =~ m/(^.*$)/)[0]),"\n";'
-> 127.0.0.1
# echo -n 127.0.0.1 | perl -n -e 'print (($_ =~ m/(^*$)/)[0]),"\n";'
->

不,它没有。 Perl 工作正常。 ^.*$ 匹配字符串,^*$ 不匹配 => .NET 的正则表达式实现已损坏,它不像 MS 声称的那样像 Perl 5 那样工作。

关于c# - 为什么 ^*$ 匹配 "127.0.0.1",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/221520/

相关文章:

regex - 为什么 POSIX "printable characters"类不匹配简单字符串?

javascript - 了解 jQuery 源代码中的空白正则表达式

c# - 与 SAP 集成

javascript - 如何使用 REGEX 匹配和不匹配子字符串

regex - 如何在单元格内和循环中使用 Microsoft Excel 中的正则表达式 (Regex)

c# - 缺少上下文菜单的库

php - 使用 XPATH 删除 <p><strong><br/> </strong></p>

c# - 通用对象需要强制转换,即使它实现了所需的接口(interface)

c# - 如果您能够修改源代码,为什么还要使用扩展方法?

c# - 在 C# 中将字节读入结构