如何在正则表达式中排除部分内容?

3

我对使用正则表达式还比较陌生,但我可以想出如何从字符串中提取特定数字。

假设字符串包含任意数量的空格或随机文本,并且其中某个地方是这样的内容:"Value: $1000.00"。

为了检索该值,我目前正在使用以下方法:

string value = Convert.ToString(Regex.Match(BodyContent, @"Value:[ \t]*\$?\d*(\.[0-9]{2})?", RegexOptions.Singleline));

现在变量'value'中存储着"Value: $1000.00"。

我的问题是,使用正则表达式是否可以使用'Value:'来找到数值,但只将实际数值(即1000.00)存储在'value'变量中?


请注意,Singleline选项对您没有任何作用。它允许.元字符匹配换行符,但是在您的正则表达式中出现.的唯一位置是为了匹配字面意义上的 .而进行转义。 - Alan Moore
2个回答

3

一般而言,要完成像这样的任务,您至少有三个选项:

  • 使用lookarounds (?=...), (?<=...),以便精确匹配您想捕获的内容。
    • 某些语言对lookbehinds的支持有限。
  • 使用捕获组(...)来捕获特定字符串。
    • 几乎所有正则表达式都支持。
  • 您还可以只取匹配结果的substring
    • 如果要裁剪的前缀/后缀长度是已知常量,则效果很好。

参考资料


示例

给定以下测试字符串:

i have 35 dogs, 16 cats and 10 elephants

以下是一些正则表达式模式的匹配结果:

您还可以进行多次捕获,例如:

  • (\d+) (猫|狗) 可以匹配出 2 个结果 (在 rubular.com 上查看)
    • 结果 1: 35 狗
      • 第一组捕获了 35
      • 第二组捕获了
    • 结果 2: 16 猫
      • 第一组捕获了 16
      • 第二组捕获了

这个问题的解决方案

在这种情况下,使用捕获组要简单得多(在ideone.com上查看):

var text = "Blah blah Value: $1000.00 and more stuff";
string value = Convert.ToString(
   Regex.Match(
     text,
     @"Value:[ \t]*\$?(\d*(\.[0-9]{2})?)",
     RegexOptions.Singleline
   ).Groups[1]
);

唯一添加的内容是:
  • 在模式中添加了一对匹配数字部分的括号
  • 访问 Match 对象的 .Groups[1]

\d+(?= cats) -> 16 这是我想使用的那个,但我该如何更改我的正则表达式以使其像那个一样工作?我已尝试过这个:@"(?=Value:[ \t]$?)\d(.[0-9]{2})?" - Immanu'el Smith
1
@Axilus:由于在这种情况下“Value:”是前缀,因此您需要使用反向引用“(?<=...)”,而不是前瞻。虽然在这些情况下通常只使用捕获组更为常见。在这里使用前瞻有点过度设计。 - polygenelubricants

2
在.NET中,您需要获取匹配对象,然后访问其Groups属性:
Match m = Regex.Match(BodyContent, @"Value:[ \t]*\$?(?<amount>\d*(\.[0-9]{2})?)", RegexOptions.Singleline);
string value = null;

if (m.Success)
{
    value = m.Groups["amount"].Value;
}

语法 (?<amount> ... ) 创建一个命名捕获组,并通过名称在 m.Groups 集合中存储。

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