18.jun。 7nočiod515,00 EUR
这里我想用正则表达式获得515,00。
Regex regularExpr = new Regex(@rule.RegularExpression,
RegexOptions.Compiled | RegexOptions.Multiline |
RegexOptions.IgnoreCase | RegexOptions.Singleline |
RegexOptions.IgnorePatternWhitespace);
tagValue.Value = "18.jun. 7 noči od 515,00 EUR";
Match match = regularExpr.Match(tagValue.Value);
object value = match.Groups[2].Value;
正则表达式是:\d+((.\d+)+(,\d+)?)?
但我总是得到一个空字符串(“”)。如果我在Expresso中尝试这个正则表达式,我得到一个包含3个值的数组,第三个是515,00。
我的C#代码有什么问题,我得到一个空字符串?
答案 0 :(得分:5)
你的正则表达式匹配18
(因为小数部分是可选的),match.Groups[2]
指的是第二个捕获括号(.\d+)
,它应该正确读取(\.\d+)
并且没有'参与比赛,因此返回空字符串。
您需要更正正则表达式并迭代结果:
StringCollection resultList = new StringCollection();
Regex regexObj = new Regex(@"\d+(?:[.,]\d+)?");
Match matchResult = regexObj.Match(subjectString);
while (matchResult.Success) {
resultList.Add(matchResult.Value);
matchResult = matchResult.NextMatch();
}
然后 resultList[2]
将包含您的匹配。
答案 1 :(得分:4)
确保在创建正则表达式时正确转义了所有内容。
Regex re = new Regex("\d+((.\d+)+(,\d+)?)?")
与
非常不同Regex re = new Regex(@"\d+((.\d+)+(,\d+)?)?")
你可能想要第二个。
答案 2 :(得分:2)
我怀疑你在Expresso中获得的结果与此相同:
string s = "18.jun. 7 noči od 515,00 EUR";
Regex r = new Regex(@"\d+((.\d+)+(,\d+)?)?");
foreach (Match m in r.Matches(s))
{
Console.WriteLine(m.Value);
}
换句话说,它不是您所看到的第二个捕获组的内容,而是第三个匹配。此代码更清楚地显示了它:
Console.WriteLine("{0,10} {1,10} {2,10} {3,10}",
@"Group 0", @"Group 1", @"Groups 2", @"Group 3");
Regex r = new Regex(@"\d+((.\d+)+(,\d+)?)?");
foreach (Match m in r.Matches(s))
{
Console.WriteLine("{0,10} {1,10} {2,10} {3,10}",
m.Groups[0].Value, m.Groups[1].Value, m.Groups[2].Value, m.Groups[3].Value);
}
输出:
Group 0 Group 1 Group 2 Group 3
18
7
515,00 ,00 ,00
关于正则表达式本身。如果您只想匹配价格而不是其他数字,则需要更具体。例如,如果您知道,00
部分将始终存在,则可以使用此正则表达式:
@"(?n)\b\d+(\.\d+)*(,\d+)\b"
(?n)
是ExplicitCapture
选项的内联形式,可将这两个捕获组转换为非捕获组。在 指定的RegexOptions中,唯一有效的是Compiled
,这会加速正则表达式的匹配,但代价是减慢其构造并占用内存。 \b
是一个单词边界。
看起来你在构造它们时会盲目地将所有这些修饰符应用于每个正则表达式,这不是一个好主意。如果特定正则表达式需要某个修饰符,您应该尝试使用内联修饰符在正则表达式中指定它,就像我使用(?n)
一样。