我不明白,为什么会出现下面的正则表达式:
^*$
匹配字符串“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/