gpt4 book ai didi

c# - 如何使用正则表达式匹配类似 CSV 的字符串中的数字和数字范围?

转载 作者:太空狗 更新时间:2023-10-29 21:16:43 25 4
gpt4 key购买 nike

通常,我喜欢正则表达式的挑战,甚至更喜欢解决它们。
但我似乎有一个我无法弄清楚的案例。

我有一个由分号分隔的值字符串,例如 CSV 行,看起来像这样: ojit_代码

在这一行中,我想匹配所有整数和整数范围,以便稍后提取它们。可能只有单个值(没有分号)。

经过大量搜索,我设法写下了这个表达式:
ojit_代码

我正在使用的测试字符串:

  1. 123-234;FOO-456;45-67;FOO-FOO;890;FOO-123;11-22;123;123;44-55;098-567;890;123-FOO;
  2. (?:^|;)(?<range>\d+-\d+)(?:$|;)|(?:^|;)(?<integer>\d+)(?:$|;)
  3. 123
  4. 123-234;FOO-456;45-67;FOO-FOO;890;FOO-123;11-22;123;123;44-55;098-567;890;123-FOO;
  5. 123-456
  6. 123-FOO

第 1 行和第 3 行正确匹配,第 4,5 6 行不匹配。
在第 2 行中,两个值中只有一个值被正确匹配。

这是 regex101.com 的链接,说明了它:https://regex101.com/r/zA7uI9/5

我还需要分别选择整数和范围(在不同的组中)。

Note: I found a question that could help me and tried its answer (by adapting it) but it didn't work.
Regular expression for matching numbers and ranges of numbers

你知道我错过了什么吗?

将“使用”此正则表达式的语言是 C#,但我不知道它是否对我的问题有用。

由 barlop 添加

这是当前正则表达式给他的匹配项,如 regex101.com 链接所示

以及他的 FOO-123 的这个测试字符串

123-234
45-67
890
11-22
123
098-567

所以他的正则表达式似乎遗漏了 123、44-45 和末尾的 89 之一。

最佳答案

C# CSV 字符串解析

使用内置的 CSV 解析器并分别检查每个字段:

using Microsoft.VisualBasic.FileIO;
....
var str = "123-234;FOO-456;45-67;FOO-FOO;890;FOO-123;11-22;123;123;44-55;098-567;890;123-FOO;";
var csv_parser = new TextFieldParser(new StringReader(str));
csv_parser.HasFieldsEnclosedInQuotes = false; // Fields are not enclosed with quotes
csv_parser.SetDelimiters(";"); // Setting delimiter
string[] fields;
var range_fields = new List<string>();
var integer_fields = new List<string>();
while (!csv_parser.EndOfData)
{
fields = csv_parser.ReadFields();
foreach (var field in fields)
{
if (!string.IsNullOrWhiteSpace(field) && field.All(x => Char.IsDigit(x)))
{
integer_fields.Add(field);
Console.WriteLine(string.Format("Intger field: {0}", field));
}
else if (!string.IsNullOrWhiteSpace(field) && Regex.IsMatch(field, @"\d+-\d+"))
{
range_fields.Add(field);
Console.WriteLine(string.Format("Range field: {0}", field));
}
}
}
csv_parser.Close();

结果是:

Range field: 123-234
Range field: 45-67
Intger field: 890
Range field: 11-22
Intger field: 123
Intger field: 123
Range field: 44-55
Range field: 098-567
Intger field: 890

修复正则表达式方法

正则表达式失败的原因是您实际上 使用 非捕获组的定界符(即 (?:^|;)( ?:$|;) 仍然匹配文本,该文本附加到匹配值,并且正则表达式索引前进到 ; 之后的位置,字符串的开始/结束)。

您需要使用的是 lookarounds 。它们不使用文本,它们只是检查是否可以在当前位置之前或之后找到与环视模式匹配的某些文本。因此,您有机会获得重叠匹配项,这是环视非常方便的场景之一。

(?<=^|;)((?<range>\d+-\d+)|(?<integer>\d+))(?=$|;)

Ojit_a

还有一个不错的图表:

regex demo for a .NET regex at a .NET regex syntax supporting RegexStorm

注意 enter image description here 的使用:通过这种方式,我们避免使用编号(即未命名)捕获组捕获子匹配,​​而仅获取命名捕获(正是我们需要的)。

RegexOptions.ExplicitCapture flag :

var s = "123-234;FOO-456;45-67;FOO-FOO;890;FOO-123;11-22;123;123;44-55;098-567;890;123-FOO;";
var rx = new Regex(@"(?<=^|;)((?<range>\d+-\d+)|(?<integer>\d+))(?=$|;)", RegexOptions.ExplicitCapture);
var result = rx.Matches(s)
.Cast<Match>()
.Select(x => x.Groups["range"].Success ?
x.Groups["range"].Value : x.Groups["integer"].Value
).ToList();
foreach (var x in result)
Console.WriteLine(x);

关于c# - 如何使用正则表达式匹配类似 CSV 的字符串中的数字和数字范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37555560/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com