【问题标题】:Parsing two messy numbers with .NET regex使用 .NET 正则表达式解析两个凌乱的数字
【发布时间】:2017-11-18 05:53:56
【问题描述】:

我有一个有趣的数字数据集,需要替换。如何使用 .NET 风格的正则表达式(可能带有环视)来使用 以下算法解析每行中的第一个和第二个数字:

大于 15 个符号的字符串包含两个数字,在第 7 个符号之后由第一次出现的 [\s\p{P}] 分隔,应将其一分为二。一个正则表达式应该提取第一个子字符串(包含数字、空格、标点符号)。第二个正则表达式提取后半部分。

对于没有合理定义的分隔符的数字,我无能为力。在下面的示例中,前 10 行是要拆分的主题。不能拆分的字符串应该由两个正则表达式中的任何一个来提取。不用担心\n;这些字符串是单独处理的。

42977424427-77927299
62 92764949 44922672
96649274796/46262299
62-96247469,74292792
69227679/69267664
47694274/42929726
42977424427/77927299
97247-2666/7224-4767
89 3644-883436749503
78-99733017785-01627
967224267
6672-2222
97694629646797496
962 44776699
942 76699466
24796427466476967
99 98448999068440722

所以,第一个正则表达式会返回:

42977424427
62 92764949
96649274796
62-96247469
69227679
47694274
42977424427
97247-2666
89 3644
78-99733017785
967224267
6672-2222
97694629646797496
962 44776699
942 76699466
24796427466476967
99 98448999068440722

第二个正则表达式语句将返回

77927299
44922672
46262299
74292792
69267664
42929726
77927299
7224-4767
883436749503
01627

Here is我(失败)尝试提取第二组数字:

(?=[\d \p{P}]{15,})[\s\p{P}][\d\p{P}]{,8}

【问题讨论】:

  • 如果您决定降低该问题的评分,请说明如何改进该问题。无声的降级适得其反。我仍然有问题,仍然需要社区的帮助。
  • 我不知道,也许有人觉得你想占他们便宜,或者第二次觉得你的尝试很糟糕,不认为它是真正的尝试。或者第三,有些人可能会发现您的问题陈述不清楚,没有经过深思熟虑,并且您的示例没有结论。不过,别介意,我没有投反对票。
  • @wp78de:谢谢。我也有同样的想法,因此,在尝试了几个小时后才发布了我的最佳尝试。我发现这个问题很好,但欢迎提出建议。有一个明确的解释,我期望有一个明确的答案。请注意,这是来自真实(混乱)世界的问题;我花时间制作了一个“公开”的样本集。
  • @OlegMelnikov 你是说你需要超过 15 个符号。但是,您仍然希望匹配具有少于 15 个符号的字符串,例如 9672242676672-2222962 44776699942 76699466。请澄清
  • @Gurman:我只想将字符串解析为两个,前提是它足够长(大约 15 个符号)并且在第 7 个符号之后有一个分隔符。否则,保持原样。这有意义吗?

标签: .net regex string split regex-lookarounds


【解决方案1】:

也许你可以试试这个正则表达式:

^(.{7}\d*)(?:[^\d\n](.*))?$

Click fo Demo

说明:

  • ^ - 断言字符串的开头
  • (.{7}\d*) - 匹配 7 次出现的任何字符,但换行符除外。接下来是 0+ 次出现的数字。第 1 组中捕获了整个价值
  • (?:[^\d\n](.*))? - 匹配既不是数字也不是换行符的字符。然后是 0+ 次出现的任何字符,但在 Group2 中捕获的换行符除外。 ? 最后是让这个匹配可选
  • $ - 断言字符串的结尾

另一个正则表达式:

^([\d .,?!'":;_-]{7}\d*)(?:[^\d\n]([\d .,?!'":;_-]*))?$

【讨论】:

  • 太棒了!我认为这可能有效。试一试全套。
  • 这可能有效,但它使用 .NET 风格的正则表达式捕获整个字符串。不过,以 PHP 风格工作。有没有办法为 .NET 调整它?我想 .NET 类似于 javascript regex101.com/r/u6X8BQ/4
  • 在 php 中它也匹配完整的字符串。您只需要从 Group1 和 Group2 获取结果。请参阅我提供的演示链接中右侧的 group1 和 group2 的值。
  • 当我尝试它时,.NET 的RegexReplace() 仍然捕获整个字符串,而不仅仅是第一组或第二组。有什么建议吗?
  • 太棒了!谢谢。我想出了其余的。这正是我所需要的:)
【解决方案2】:

我最终得到了一个安静的类似pattern

^([\d\s\p{P}]{7}\d*)(?:[^\d\n]([\d\p{P}]+))?$

允许您根据需要从捕获组中获取值:

using System;
using System.Text.RegularExpressions;

public class Example
{
    public static void Main()
    {
        string pattern = @"^([\d\s\p{P}]{7}\d*)(?:[^\d\n]([\d\p{P}]+))?$";
        string input = @"42977424427-77927299
62 92764949 44922672
96649274796/46262299
62-96247469,74292792
69227679/69267664
47694274/42929726
42977424427/77927299
97247-2666/7224-4767
89 3644-883436749503
78-99733017785-01627
967224267
6672-2222
97694629646797496
962 44776699
942 76699466
24796427466476967
99 98448999068440722";
        RegexOptions options = RegexOptions.Multiline;

        foreach (Match m in Regex.Matches(input, pattern, options))
        {
            Console.WriteLine("{0}.....{1}", m.Groups[1].Value, m.Groups[2].Value);
        }
    }
}

只需使用组或根据需要将最终字符串粘合在一起。

这里有一个模式可以实现你最初的拆分想法:

(?=(?:(?:[\d\s\p{P}]{15,}).))(?<=.{7})[\s\p{P}]

【讨论】:

猜你喜欢
  • 2023-03-08
  • 2020-08-08
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 2023-03-06
  • 2022-01-25
相关资源
最近更新 更多