我必须从文本中解析一堆统计数据,它们都被格式化为数字。
例如,这一段:
纽约市 81.8% 的 3 至 8 年级学生达到或超过年级水平的数学标准,而纽约州其他地区的学生这一比例为 88.9%。
我只想匹配 81 和 88 数字,而不是后面的“.8”和“.9”。
我怎样才能做到这一点?我听说过反向引用或前瞻之类的术语。这些会有帮助吗?
我正在使用 C#。
编辑:在上面的例子中,我需要得到“3”和“8”。这只是一个简单的例子,但我需要几乎所有的数字。
/[^.](\d+)[^.]/
如下所述,只需使用 MatchObj.Groups(1) 来获取数字。
如果您不想处理组,则可以像您说的那样使用前瞻;此模式查找字符串中所有十进制数的整数部分:
Regex integers = new Regex(@"\d+(?=\.\d)");
MatchCollection matches = integers.Matches(str);
matches
将包含81
和88
。如果您想匹配任何数字的整数部分(无论是否为十进制),您可以改为搜索不以 a 开头的整数.
:
Regex integers = new Regex(@"(?<!\.)\d+");
这一次,匹配项将包含81
、3
和。8
88
完整的 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
尝试:
[0-9]*(?=[3])
它使用前瞻来仅匹配后跟小数点的数字。
C#代码:
Regex regex = new Regex("[0-9]+(?=[.])");
MatchCollection matches = regex.Matches(input);
[^.](\d+)
从您的示例中,这将匹配“81”、“3”、“8”、“88”
在获得号码之前,您会获得一个额外的字符,但您可以在代码中将其删除。
/(\d+)\.\d/g
这将匹配任何后面有小数的数字(我认为这是你想要的),但只会捕获小数点之前的数字。\d
只会捕获数字(与 [0-9] 相同),因此它使这变得非常简单。
编辑:如果你也想要三个和八个,你甚至不需要检查小数点。
Edit2:抱歉,已修复它,因此它会忽略所有小数位。
/(\d+)(?:\.\d+)?/g
尝试使用
/(\d+)((\.\d+)?)/
这基本上意味着将一个数字序列和一个可选的小数点与另一个数字序列匹配。然后,MatchObj.Groups(1)
用于第一个匹配值,忽略第二个。
这不是您询问的语言,但它可以帮助您思考问题。
$ 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