.NET正则表达式匹配可以匹配空字符串。

4

我有这个

模式:

[0-9]*\.?[0-9]*

目标:

X=113.3413475 Y=18.2054775

我希望您能够匹配这些数字。在测试软件中,如http://regexpal.com/和Regex Coach中,它们的匹配效果很好。
但是,在Dot net和http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx中,我得到了以下结果:
Found 11 matches:

1.
2.
3.
4.
5.
6.  113.3413475
7.
8.
9.
10. 18.2054775
11.

String literals for use in programs:

C#
    @"[0-9]*[\.]?[0-9]*"

有人知道为什么我会得到所有这些空匹配吗?

谢谢和问候, Kevin

6个回答

11

是的,这将匹配空字符串。看看这个:

[0-9]* - zero or more digits
\.?    - an optional period
[0-9]* - zero or more digits

所有内容都是可选的,所以空字符串也可以匹配。

看起来你总是希望有数字出现 在某个地方,例如:

[0-9]+\.[0-9]*|\.[0-9]+|[0-9]+

(顺序很重要,因为您希望它尽可能地充分利用。)

对我来说这个可以。

using System;
using System.Text.RegularExpressions;

class Test
{
    static void Main(string[] args)
    {
        string x = "X=113.3413475 Y=18.2054775";
        Regex regex = new Regex(@"[0-9]+\.[0-9]*|\.[0-9]+|[0-9]+");
        var matches = regex.Matches(x);
        foreach (Match match in matches)
        {
            Console.WriteLine(match);
        }
    }
}

输出:

113.3413475
18.2054775

诚然,可能有更好的方法去做它 :)


1
@Cubicle.Jockey:在像“123”、“123。”或“.123”这样的情况下,这种方法会失败——我相信这正是OP想要的。 - Jon Skeet
我看到了很好的发现。在我的测试中运行后,它表现得非常好。+1 - Cubicle.Jockey

3

另一种选择是保留您原来的正则表达式,并且只断言它必须有一个数字(也许在点之后):

[0-9]*\.?[0-9]*

前往:
(?=\.?[0-9])[0-9]*\.?[0-9]*

2

试试这个:

[0-9]+(\.[0-9]+)?

与Jon Skeet先生的答案稍有不同,它不匹配.45,而是要求仅为数字(例如8)或真实小数(例如8.10.1)。


0
Regex pattern = new Regex( @"[0-9]+[\.][0-9]+");

string info = "X=113.3413475 Y=18.2054775";

MatchCollection matches = pattern.Matches(info);

int count = 1;
foreach(Match match in matches)
{
    Console.WriteLine("{0} : {1}", count++, match.Value);
}

//output
//1 : 113.3413475
//2 : 18.2054775

将您的*替换为+,并从您的句点情况中删除?

编辑:来自上面的对话:@"[0-9]+.[0-9]*|.[0-9]+|[0-9]+",是更好的情况。捕获123、.123、123.123等。


哇,我应该在发布之前刷新一下..... :) 好的,就像他们说的那样。你可以在 LinqPad 中运行我的示例。 - Cubicle.Jockey

0

关键问题在于*,它表示“匹配前面的字符零次或多次”。空字符串匹配零个或多个数字,这就是为什么你会得到所有这些匹配结果。

将你的两个*改成+,你就能得到想要的结果了。


0
这个正则表达式的问题在于它在所有字段中都是可选的,因此空字符串也会被匹配。我建议添加所有情况。根据正则表达式,我看到您想要带或不带小数点的数字,以及带或不带一组小数位。您可以首先分离只包含数字的那些[0-9]+,然后是那些包含数字加上一个点的[0-9]+\.,最后用|(或)将它们全部连接起来。
正则表达式的问题在于它允许不是真实数字的情况,例如,第一组数字和最后一组数字为空(只有一个点),因此您必须明确列出有效的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接