C# 为什么^*$matches";127.0.0.1“;
我不明白,为什么下面的正则表达式C# 为什么^*$matches";127.0.0.1“;,c#,regex,C#,Regex,我不明白,为什么下面的正则表达式 ^*$ 匹配字符串“127.0.0.1”?使用Regex.IsMatch(“127.0.0.1”,“^*$” 使用Expresso,它不匹配,这也是我所期望的。使用表达式^.*$与字符串匹配,这也是我所期望的 从技术上讲,^*$应该多次匹配字符串/行的开头,然后是字符串/行的结尾。似乎*被隐式地视为* 我错过了什么 编辑: 运行以下命令以查看问题的示例 using System; using System.Text.RegularExpressions; n
^*$
匹配字符串“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实现避免抛出异常,即使从技术上讲它是一个不正确的表达式。但这真的是我们想要的吗?使用,我可以看到它在“127.0.0.1”之后的“null”标记上匹配。似乎因为您没有指定令牌,加号匹配零次或多次,所以它匹配“null”令牌
以下正则表达式应该可以工作:
^+$
理论上你是对的,它不应该匹配。但这取决于内部实现的工作方式。大多数正则表达式都是impl。将从前面提取正则表达式并去掉“^”(注意它必须从字符串的开头匹配),从末尾去掉$(注意它必须到字符串的结尾),剩下的只是“*”,而“*”本身就是一个有效的正则表达式。您正在使用的实现在如何处理它方面是错误的。您可以尝试将“^*$”替换为“*”;我想它也会匹配所有东西。似乎实现将单个星号视为“.*”
根据ISO/IEC 9945-2:1993标准(该标准也在中描述),它被破坏。它之所以被打破,是因为标准规定,在“^”字符之后,星号没有任何特殊意义。这意味着“^*$”实际上应该只匹配一个字符串,而这个字符串是“*”
引用标准:
星号是特殊的,除非使用:
- 在括号表达式中
- 作为整个BRE的第一个字符(在首字母^之后,如果有)
- 作为子表达式的第一个字符(在首字母^之后,如果有);请参见匹配多个字符的BRE
因此,如果它是第一个字符(如果存在,^不算作第一个字符),则没有特殊意义。这意味着在这种情况下,星号应该只匹配一个字符,这是一个星号
更新
微软说
Microsoft.NET Framework常规
表达式包含了最多
其他常规功能的流行特性
表达式实现,例如
Perl和awk中的那些。设计为
与Perl5兼容
.NET Framework正则表达式
表达式包含尚未包含的功能
可以在其他实现中看到,例如
从右到左匹配和动态
汇编
资料来源:
好的,让我们测试一下:
# 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工作正常。^.*$匹配字符串,^*$NOTS=>.NET的正则表达式实现已中断,并且它的工作方式与MS声称的Perl 5不同。星号(*)匹配前面的元素零次或更多次。如果需要一个或多个,请使用+运算符而不是*
您要求它匹配可选的字符串起始标记和字符串结束标记。也就是说,如果我们省略了字符串标记的开头,那么您只能查找字符串标记的结尾。。。这将匹配任何字符串
我真的不明白你想做什么。如果您能给我们提供更多信息,那么也许我可以告诉您应该做什么:)您实际上是在说“匹配一个不包含任何内容的字符串”。所以它会匹配的。^和$binding在这种情况下并没有真正的区别。除了非法的regexp之外,您想要编写的内容很可能不是这样
您可以这样写:“^*$
应该多次匹配字符串/行的开头,然后是字符串/行的结尾”,这意味着您需要多行regexp,但您忘记了,如果行之间没有行尾,行不能开始两次
此外,您在需求中提出的要求实际上符合“127.0.0.1”:)A^
不是换行/回车,而是一行的开始,$
不仅仅是一行的换行,而是一行的结束
另外,*
尽可能匹配(设置了ungreedy模式时除外),这意味着regexp/^.*$/
regexp将匹配所有内容。如果要管理换行符,必须显式地编写这些代码
希望这能澄清一些事情:)如果你尝试的话
Regex.Match("127.0.0.1", "^*1$")
您将看到它也匹配。Match.Index属性的值为8,这意味着它匹配的是最后一个“1”,而不是第一个。这是有意义的,因为“^*”将匹配零个或多个行的开头,并且在“1”之前有零个行的开头
考虑一下“a*1$”的匹配方式,因为“1$”之前没有“a”。所以“a*$”将与行尾匹配,就像您的示例一样
顺便说一句,MSDN文档没有提到“*”而只是简单地匹配“*”,除非转义为“\*”。“*”本身将抛出一个异常,与“*”不匹配。POSIX正则表达式标准非常古老且有限。仍在使用的少数工具