C# 中的迭代正则表达式捕获

发布于 2024-09-27 07:49:38 字数 594 浏览 6 评论 0原文

我必须读取包含多个坐标的文件。该文件的结构如下:

X1/Y1,X2/Y2,X3/Y3,X4/Y4

其中 X 和 Y 是正整数。为了解决这个问题,我想使用正则表达式(我认为这通常是一个好主意,因为模式更改时重构最少)。

因此,我开发了以下正则表达式:

Regex r = new Regex(@^(?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+))(,(?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+)))*$");

但是,当我在数据上测试此正则表达式时,例如:

1302/1425,1917/2010

正则表达式似乎只能回忆起最后一个 X、Y 和 Coor 组。在这种情况下,Coor 是“12/17”,X 是“1917”,Y 是“2010”。有没有办法生成某种树。所以我找到一个给我所有 Coor 表达式的对象,每个 Coor 下都有一个 X 和 Y 分量?

如果可能的话,我想只使用一个正则表达式,因为格式可能会更改为另一种格式。

I have to read in a file that contains a number of coordinates. The file is structured in the following way:

X1/Y1,X2/Y2,X3/Y3,X4/Y4

Where X and Y are positive integers. To solve this problem I want to use a regex (I think this is in general a good idea because of minimal refactoring when the pattern changes).

Therefore I have developed the following regex:

Regex r = new Regex(@^(?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+))(,(?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+)))*$");

However when I test this regex on data, for example:

1302/1425,1917/2010

The Regex only seems to recall the last X, Y and Coor group. In this case Coor is "12/17", X is "1917" and Y is "2010". Is there a way to generate some sort of tree. So I find an object who gives me all the Coor expressions, with under each Coor an X and Y component?

If possible, I would like to use only one Regex, this because the format could perhaps change to another one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

青衫负雪 2024-10-04 07:49:39

您可以使用 string.Splitint.Parse 轻松解决此问题,而无需任何正则表达式:

var coords = s.Split(',')
    .Select(x => x.Split('/'))
    .Select(a => new {
        X = int.Parse(a[0]),
        Y = int.Parse(a[1])
    });

如果您想使用正则表达式来验证 字符串,您可以这样做:

"^(?!,)(?:(?:^|,)[0-9]+/[0-9]+)*$"

如果您还想使用基于正则表达式的方法来提取数据,您可以首先使用上述正则表达式验证字符串,然后按如下方式额外提取数据:

var coords = Regex.Matches(s, "([0-9]+)/([0-9]+)")
    .Cast<Match>()
    .Select(match => new
    {
        X = int.Parse(match.Groups[1].Value),
        Y = int.Parse(match.Groups[2].Value)
    });

如果您确实想使用单个正则表达式同时执行验证和数据提取,您可以使用两个捕获组并在每个组的 Captures 属性中查找结果。这是使用单个正则表达式执行验证和数据提取的一种方法:

List<Group> groups =
    Regex.Matches(s, "^(?!,)(?:(?:^|,)([0-9]+)/([0-9]+))*$")
         .Cast<Match>().First()
         .Groups.Cast<Group>().Skip(1)
         .ToList();

var coords = Enumerable.Range(0, groups[0].Captures.Count)
    .Select(i => new
    {
        X = int.Parse(groups[0].Captures[i]),
        Y = int.Parse(groups[1].Captures[i])
    });

但是,您可能需要考虑与基于 string.Split 的解决方案相比,该解决方案的复杂性是否值得。

You can quite easily solve this without any regular expression by using string.Split and int.Parse:

var coords = s.Split(',')
    .Select(x => x.Split('/'))
    .Select(a => new {
        X = int.Parse(a[0]),
        Y = int.Parse(a[1])
    });

If you want to use a regular expression to validate the string you could do it like this:

"^(?!,)(?:(?:^|,)[0-9]+/[0-9]+)*$"

If you want to use a regular expression based approach also for extracting the data you could first validate the string using the above regular expression and then extra the data as follows:

var coords = Regex.Matches(s, "([0-9]+)/([0-9]+)")
    .Cast<Match>()
    .Select(match => new
    {
        X = int.Parse(match.Groups[1].Value),
        Y = int.Parse(match.Groups[2].Value)
    });

If you really want to perform the validation and data extraction simultaneously with a single regular expression you can use two capturing groups and find the results in the Captures property for each group. Here's one way you could perform both the validation and data extraction using a single regular expression:

List<Group> groups =
    Regex.Matches(s, "^(?!,)(?:(?:^|,)([0-9]+)/([0-9]+))*$")
         .Cast<Match>().First()
         .Groups.Cast<Group>().Skip(1)
         .ToList();

var coords = Enumerable.Range(0, groups[0].Captures.Count)
    .Select(i => new
    {
        X = int.Parse(groups[0].Captures[i]),
        Y = int.Parse(groups[1].Captures[i])
    });

However you may want to consider whether the complexity of this solution is worth it compared to the string.Split based solution.

原来分手还会想你 2024-10-04 07:49:39

没有理由对如此简单的格式使用正则表达式。

只需分割字符串并使用纯字符串操作来获取坐标:

var coordinates =
  fileContent.Split(',').Select(s => {
    int pos = s.IndexOf("/");
    return new {
      X = s.Substring(0, pos),
      Y = s.Substring(pos + 1)
    };
  });

如果文件格式变得更加复杂,您可以将其重构为使用正则表达式。在那之前,像这样的简单代码更容易维护。

There is no reason to use a regular expression for such a simple format.

Just split the string and use plain string operations to get the coordinates:

var coordinates =
  fileContent.Split(',').Select(s => {
    int pos = s.IndexOf("/");
    return new {
      X = s.Substring(0, pos),
      Y = s.Substring(pos + 1)
    };
  });

If the file format gets much more complicated you can refactor it into using a regular expression. Until then, simple code like this is much easier to maintain.

鲜肉鲜肉永远不皱 2024-10-04 07:49:39

如果您使用“匹配”而不是“匹配”命令,您可能会得到您想要的东西。另外,你不能将正则表达式缩短为这样:

Regex(@"((?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+))|,)*");

You might get what you seek if you use the "Matches" rather than "Match" command. Also, can't you shorten the regex perhaps to this:

Regex(@"((?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+))|,)*");
简单 2024-10-04 07:49:39

我认为你的第一个问题是你的正则表达式有缺陷,锚点正在摆脱匹配。这是我想出的:(只是这里显示的正则表达式,没有代码)

(?(?[0-9]+)/(?[0 -9]+))

Mystagogue 也可以工作,但在逗号上产生“空白”匹配(对我来说)。

I think your first problem is that your regex is flawed, the anchors are throwing off the matching. This is the one I came up with: (just the regex shown here, no code)

(?<Coor>(?<X>[0-9]+)/(?<Y>[0-9]+))

The one Mystagogue works as well, but produces 'blank' matches on the commas (for me).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文