在某个角色之前匹配任何内容的正则表达式?

时间:2009-06-03 16:42:02

标签: c# regex parsing lookahead

我必须从文本中解析一堆统计信息,并且它们都被格式化为数字。

例如,本段:

  

总计纽约的81.8%   3到8年级的城市学生是   达到或超过年级数学   标准,相比之下,88.9%   在该州其他地方的学生。

我想只匹配81和88号码,而不是后面的“.8”和“.9”。

我该怎么做?我听说过反向引用或前瞻等术语。这有什么帮助吗?

我正在使用C#。

编辑: 我需要在上面的例子中得到“3”和“8”。这只是一个简单的例子,但我几乎需要所有的数字。

8 个答案:

答案 0 :(得分:3)

/[^.](\d+)[^.]/

如下所述,只需使用MatchObj.Groups(1)来获取数字。

答案 1 :(得分:2)

如果你不想与群体打交道,你可以像你说的那样使用先行;此模式查找字符串中所有十进制数的整数部分:

Regex integers = new Regex(@"\d+(?=\.\d)");
MatchCollection matches = integers.Matches(str);

matches将包含8188。如果您想匹配任何数字的整数部分(小数或非小数),您可以搜索不以.开头的整数:

Regex integers = new Regex(@"(?<!\.)\d+");

这次,匹配将包含813888

答案 2 :(得分:2)

完整的C#解决方案:

/// <summary>
/// Use of named backrefence 'roundedDigit' and word boundary '\b' for ease of
/// understanding
/// Adds the rounded percents to the roundedPercents list
/// Will work for any percent value
/// Will work for any number of percent values in the string
/// Will also give those numbers that are not in percentage (decimal) format
/// </summary>
/// <returns>true if success, false otherwise</returns>
public static bool TryGetRoundedPercents(string digitSequence, out List<string> roundedPercents)
{
    roundedPercents = null;
    string pattern = @"(?<roundedDigit>\b\d{1,3})(\.\d{1,2}){0,1}\b";

    if (Regex.IsMatch(digitSequence, pattern))
    {
        roundedPercents = new List<string>();
        Regex r = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);

        for (Match m = r.Match(digitSequence); m.Success; m = m.NextMatch())
            roundedPercents.Add(m.Groups["roundedDigit"].Value);

        return true;
    }
    else
        return false;
}

从您的示例中返回81,3,8和88

答案 3 :(得分:1)

尝试:

[0-9]*(?=[3])

它使用前瞻只匹配数字后跟小数点。

C#代码:

Regex regex = new Regex("[0-9]+(?=[.])");
MatchCollection matches = regex.Matches(input);

答案 4 :(得分:1)

[^.](\d+)

从您的示例中,这将匹配“81”,“3”,“8”,“88”

在获得号码之前,你会得到一个额外的角色,但你可以在你的代码中修改它。

答案 5 :(得分:0)

/(\d+)\.\d/g

这将匹配任何后跟小数的数字(我认为这是你想要的),但只会捕获小数点前的数字。 \d只会捕获数字(与[0-9]相同),所以这很简单。

编辑:如果你想要三个和八个,你甚至不需要检查小数。

Edit2:抱歉,修正了它会忽略所有小数位。

/(\d+)(?:\.\d+)?/g

答案 6 :(得分:0)

尝试使用 /(\d+)((\.\d+)?)/

这基本上意味着将一系列数字和一个可选的小数点与另一个数字序列相匹配。然后,使用MatchObj.Groups(1)作为第一个匹配值,忽略第二个匹配值。

答案 7 :(得分:0)

这不是您所询问的语言,但它可能会帮助您思考问题。

$ echo "A total of 81.8 percent of New York City students in grades 3 to 8 are meeting or exceeding grade-level math standards, compared to 88.9 percent of students in the rest of the State." \
| fmt -w 1 | sed -n -e '/^[0-9]/p' | sed -e 's,[^0-9].*,,' | fmt -w 72
81 3 8 88

第一个fmt命令要求以下命令分别考虑每个单词。 “sed -n”命令仅输出以至少一个数字开头的单词。第二个sed命令删除单词中的第一个非数字字符,以及之后的所有内容。第二个fmt命令将所有内容组合成一行。

$ echo "This tests notation like 6.022e+23 and 10e100 and 1e+100." \
| fmt -w 1 | sed -n -e '/^[0-9]/p' | sed -e 's,[^0-9].*,,' | fmt -w 72
6 10 1