C# 与正则表达式存在错误匹配,don';我不知道如何修理
我正在尝试检测模式: 字符串“BP”后跟2或4个双精度值(我稍后将捕获这些值),所有值都由空格分隔 例如:C# 与正则表达式存在错误匹配,don';我不知道如何修理,c#,regex,C#,Regex,我正在尝试检测模式: 字符串“BP”后跟2或4个双精度值(我稍后将捕获这些值),所有值都由空格分隔 例如: BP 1.0 3.5 BP-1e-3 0.72 3.7 1.22e2 为了检测double,我使用了我从中获得的模式[+\-]?(?:0[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+) 不幸的是,在测试了几个字符串之后,我发现我的代码无法区分字符串BP后面是2或4个数字。下面是一些测试用例: void Main() { var testString =
BP 1.0 3.5
BP-1e-3 0.72 3.7 1.22e2
[+\-]?(?:0[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)
不幸的是,在测试了几个字符串之后,我发现我的代码无法区分字符串BP
后面是2或4个数字。下面是一些测试用例:
void Main()
{
var testString = "BP -1.23e4 5.67";
var mspaces = @"\s*"; // meaning as many spaces as you want
var cdouble = @"([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)"; // meaning capture a double
var shortPattern = String.Join("", mspaces, "BP", mspaces, cdouble, mspaces, cdouble, mspaces);
var longPattern = String.Join("", mspaces, "BP", mspaces, cdouble, mspaces, cdouble, mspaces, cdouble, mspaces, cdouble, mspaces);
var bpShort = Regex.Match(testString, shortPattern, RegexOptions.IgnoreCase);
var bpLong = Regex.Match(testString, longPattern, RegexOptions.IgnoreCase);
if (bpLong.Success)
{
Console.WriteLine("Long pattern detected"); // !!FALSE-MATCH!!
}
if (bpShort.Success)
{
Console.WriteLine("Short pattern detected");
}
}
在本例中,即使只有两个数字(-1.23e4
和5.67
),代码也会匹配4个不同的数字(-1.23e4
,5.
,6
,7
)
也许我添加了圆括号来表示我想要捕获所有数字子元素是错误的,或者我应该进一步表示一个带有空格或字符串结尾的双端点,我不知道?这很明显。正则表达式总是希望找到尽可能多的匹配项。因此,如果您查找四个数字,正则表达式将尽最大努力分割字符串,以便匹配四个数字 要解决此问题,需要在两个匹配项之间强制使用空格 这可以通过更换以下部件来实现:
var mspaces = @"\s*";
作者:
(+
表示一个或多个,而*
表示零或多个,因此正则表达式可以决定不在两个数字之间使用空格。)
您还应该删除正则表达式连接中的起始空格。从而取代:
String.Join("", mspaces, "BP"...
作者:
以及尾随mspace
。在这种情况下,一个得到
也许您不想匹配像abp15
这样的字符串,因为A
和BP
之间必须有一些空格。在这种情况下,您可以使用@“\b”
最后,正如@MattBurland所说,任何有四个数字的模式当然是有两个数字的模式。如果希望字符串以结尾,可以在结尾使用
$
。如果希望字符串以BP
开头,可以在前面使用^
。看起来像是非贪婪匹配。作为旁注,如果你的分隔符是空的,你可以使用<代码>字符串.CONTAG< /COD>而不是<代码>连接< /代码>。为什么不与^
和$
)可以解决这个问题。非常感谢您提供这些清晰的解释,这很有意义。使用$
也比先测试长字符串再测试短字符串要好得多(这就是我想要区分两者的方式)。对于信息,我正在解析的字符串是从文件中读取的过滤器描述。我有类似BP1.0 2.0
(带通介于1.0和20之间)或BR 1.0 1.1 2.0 2.1
(带阻,第一次转换为1.0到1.1,第二次转换为2.0到2.1)。有时在BP
,BR
,HP
字母之前有额外的空格…修剪就足够了。。
String.Join("", mspaces, "BP"...
String.Join("", "BP"...