Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么^*$matches";127.0.0.1“;_C#_Regex - Fatal编程技术网

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正则表达式标准非常古老且有限。仍在使用的少数工具