C# 用于捕获数字和数字范围的正则表达式

C# 用于捕获数字和数字范围的正则表达式,c#,regex,C#,Regex,我有以下字符串 Fat mass loss was 2121,323.222 greater for GPLC (2–2.4kg vs. 0.5kg) 我想抓住 212,323.222 2-2.24 0.5 i、 e.我想从字符串中得到上述三个结果, 有人能帮我处理这个正则表达式吗?好的,直到现在我才注意到C#标记。我会留下答案,但我知道这不是你期望的,看看你能不能用它做点什么。也许标题应该提到编程语言 当然可以: 在\1、\2和\3中查找子字符串。 如果是Emacs,则交换所有括号和转义

我有以下字符串

Fat mass loss was 2121,323.222 greater for GPLC (2–2.4kg vs. 0.5kg)
我想抓住

212,323.222
2-2.24
0.5
i、 e.我想从字符串中得到上述三个结果,
有人能帮我处理这个正则表达式吗?好的,直到现在我才注意到C#标记。我会留下答案,但我知道这不是你期望的,看看你能不能用它做点什么。也许标题应该提到编程语言


当然可以:

在\1、\2和\3中查找子字符串。
如果是Emacs,则交换所有括号和转义括号。

类似的内容如何:

^.*((?:\d+,)*\d+(?:\.\d+)?).*(\d+(?:\.\d+)?(?:-\d+(?:\.\d+))?).*(\d+(?:\.\d+)).*$
var input = "Fat mass loss was 2121,323.222 greater for GPLC (2-2.4kg vs. 0.5kg)";
var pattern = @"\d+(?:[,.-]\d+)*";

var matches = Regex.Matches(input, pattern);

foreach ( var match in matches )
  Console.WriteLine(match.Value);
string input = "Fat mass loss was 2121,323.222 greater for GPLC (2–2.4kg vs. 0.5kg)";
try {
    Regex rx = new Regex(@"\d+(?:[\p{Pd}\p{Pc}\p{Po}\p{C}]\d+)*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    Match match = rx.Match(input);
    while (match.Success) {
        // matched text: match.Value
        // match start: match.Index
        // match length: match.Length
        match = match.NextMatch();
    } 
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}
我想更一般一点。我有点担心贪婪

脂肪质量损失更大21323.222 对于GPLC(2-2.4kg与0.5kg)

通用提取器:

/\D+?([\d\,\.\-]+)/g
说明:

/           # start pattern
 \D+        # 1 or more non-digits
  (         # capture group 1          
   [\d,.-]+ # character class, 1 or more of digits, comma, period, hyphen
  )         # end capture group 1
/g          # trailing regex g modifier (make regex continue after last match)
很抱歉,我对c#的了解还不足以进行完整的编写,但该模式应该马上插入


请参阅:有关一些实现示例。

看起来您正在尝试查找字符串中的所有数字(数字中可能包含逗号),以及所有数字范围,如“2-2.4”。下面是一个应该有效的正则表达式:

\d+(?:[,.-]\d+)*
从C#3中,您可以这样使用它:

^.*((?:\d+,)*\d+(?:\.\d+)?).*(\d+(?:\.\d+)?(?:-\d+(?:\.\d+))?).*(\d+(?:\.\d+)).*$
var input = "Fat mass loss was 2121,323.222 greater for GPLC (2-2.4kg vs. 0.5kg)";
var pattern = @"\d+(?:[,.-]\d+)*";

var matches = Regex.Matches(input, pattern);

foreach ( var match in matches )
  Console.WriteLine(match.Value);
string input = "Fat mass loss was 2121,323.222 greater for GPLC (2–2.4kg vs. 0.5kg)";
try {
    Regex rx = new Regex(@"\d+(?:[\p{Pd}\p{Pc}\p{Po}\p{C}]\d+)*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    Match match = rx.Match(input);
    while (match.Success) {
        // matched text: match.Value
        // match start: match.Index
        // match length: match.Length
        match = match.NextMatch();
    } 
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

我说出了这样的暴行:

-?\d(?:,?\d)*(?:\.(?:\d(?:,?\d)*\d|\d))?(?:[–-]-?\d(?:,?\d)*(?:\.(?:\d(?:,?\d)*\d|\d))?)?

>巫术>代码> -d((:,d))*((::(d:(d:(d:(d),d)d))/<代码>重复两次,中间用<代码> ->代码>(注意这是一个长连字符)。


这应该注意数字以外的点和逗号,例如:
hello,23,45.2-7world
-将捕获
23,45.2-7

我注意到2–2.4kg中的连字符不是真正的连字符,而是unicode 0x2013“破折号”

这是C中的另一个正则表达式#

试验

这里是结果,我的控制台不支持打印unicode字符2013,所以它的“?”是正确匹配的

2121,323.222
2?2.4
0.5

嗯,这是一个棘手的问题,特别是因为输入字符串包含unicode字符-()而不是-()。因此,与原始字符串中的数字匹配的正确正则表达式为:

\d+(?:[\u2013,.]\d+)*
\d+(?:[\p{Pd}\p{Pc}\p{Po}]\d+)*
如果您想要更通用的方法,可以是:

\d+(?:[\u2013,.]\d+)*
\d+(?:[\p{Pd}\p{Pc}\p{Po}]\d+)*
它与破折号标点、连接符标点和其他标点匹配。请参阅以了解有关这些的更多信息

C#中的实现如下所示:

^.*((?:\d+,)*\d+(?:\.\d+)?).*(\d+(?:\.\d+)?(?:-\d+(?:\.\d+))?).*(\d+(?:\.\d+)).*$
var input = "Fat mass loss was 2121,323.222 greater for GPLC (2-2.4kg vs. 0.5kg)";
var pattern = @"\d+(?:[,.-]\d+)*";

var matches = Regex.Matches(input, pattern);

foreach ( var match in matches )
  Console.WriteLine(match.Value);
string input = "Fat mass loss was 2121,323.222 greater for GPLC (2–2.4kg vs. 0.5kg)";
try {
    Regex rx = new Regex(@"\d+(?:[\p{Pd}\p{Pc}\p{Po}\p{C}]\d+)*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    Match match = rx.Match(input);
    while (match.Success) {
        // matched text: match.Value
        // match start: match.Index
        // match length: match.Length
        match = match.NextMatch();
    } 
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

我找到了解决问题的办法

下面是给出我期望结果的正则表达式:

(([0-9]+)([–.,-]*))+
让我们试试这个:

(?=\d)([0-9,.-]+)(?<=\d)

(?=\d)([0-9,.-]+)(?/只是/这个字符串?还是一个更通用的解决方案?*用echo测试“GPLC的脂肪质量损失更大21323.222(2.2.4kg vs.0.5kg)”\grep-rnP“^.*(?:\d+,)*\d+(?:\.\d+).*(\d+)(?:\.\d+)(?:-\d+)(?:::\.\d+))。*(?:::。。。。。。。。。。*”您不应该从头到尾捕获它…您可以有一个包含许多数字的文本,只包含此示例。您不需要在字符类中转义
。在这种情况下,
-
两者都不需要(因为它位于末尾).和
\D+
不需要是非贪婪的,因为后面的第一个字符总是一个数字。\D匹配任何数字。\D是相反的,它匹配任何不是数字的字符。请参阅。(?:)表示没有捕获的群集,但我们不希望捕获每个匹配中的单个部分。例如,我们不需要“2121”、“323”和分别为“222”。我们需要整个“2121323.222”,它将是Regex.Match()返回的MatchCollection中的一个元素。我现在看到的只是数字提取部分,但是Regex如何从左到右处理不需要的字符?这就是为什么我提到\D+Oops…我应该使用Regex.Matches()而不是Regex.Match。让我来修正我的答案…谢谢你捕捉到它。Regex.Matches()将找到所有匹配的子字符串,并只返回匹配项。因此你的Regex不需要匹配不需要的部分。为什么要使用两个连字符?Matches()是否用。*包装Regex?试试这个。这是一个unicode破折号,
javascript:alert(–).charCodeAt(0))
很好!我想知道为什么我的正则表达式测试用那个连字符失败了…我开始质疑我的理智…为了更通用的方法,你可以使用“破折号标点符号”:\p{Pd}