【问题标题】:What RegEx string will find the last (rightmost) group of digits in a string?什么正则表达式字符串会在字符串中找到最后(最右边)的一组数字?
【发布时间】:2012-01-05 12:40:55
【问题描述】:

寻找一个正则表达式字符串,它可以让我找到嵌入在字符串中的最右边(如果有的话)数字组。我们只关心连续的数字。我们不关心符号、逗号、小数等。如果找到这些,应该像字母一样简单地视为非数字。

这是出于替换/递增的目的,因此我们还需要获取检测到的数字之前和之后的所有内容,以便我们可以在递增值后重建字符串,因此我们需要一个标记化的正则表达式。

以下是我们正在寻找的示例:

  • “abc123def456ghi”应该识别'456'
  • “abc123def456ghi789jkl”应该识别'789'
  • “abc123def”应该标识'123'
  • “123ghi”应该标识'123'
  • “abc123,456ghi”应该识别出'456'
  • “abc-654def”应该识别'654'
  • “abcdef”不应返回任何匹配项

作为我们想要的示例,它类似于以名称“Item 4-1a”开头,提取前缀之前的所有内容和后缀之后的所有内容的“1”。然后使用它,我们可以在代码循环中生成值“Item 4-2a”、“Item 4-3a”和“Item 4-4a”。

现在,如果我正在寻找第一组,这将很容易。我只是找到前缀的第一个 0 或多个非数字的连续块,然后是数字的 1 个或多个连续数字的块,然后到最后的所有内容都是后缀。

我遇到的问题是如何将前缀定义为包括除最后一组之外的所有(如果有)数字。我为前缀所做的一切尝试都会吞下最后一组,即使我尝试通过基本上颠倒上述方式将其锚定到最后。

【问题讨论】:

  • 您可以使用@Birei 提供的正则表达式split 并在连接之前更新第二个索引以获得所需的结果。
  • 怎么拆分?如果字符串是 a44b44c 怎么办?前缀应该是“a44b”,如果我要进行太多手动操作,那么使用已经支持命名令牌的正则表达式会失败。
  • 通过拆分,我的意思是 (Regex.Split)[msdn.microsoft.com/en-us/library/…,因此是上一条评论中的超链接。应用Regex.Split() 并为a44b44c 提供3 个令牌,即。 a44b44c
  • 啊啊!不知道那个。效果很好!

标签: c# regex


【解决方案1】:

怎么样:

^(.*?)(\d+)(\D*)$

然后增加第二组并连接所有 3。

说明:

^         : Begining of string
  (       : start of 1st capture group
    .*?   : any number of any char not greedy
  )       : end group
  (       : start of 2nd capture group
    \d+   : one or more digits
  )       : end group
  (       : start of 3rd capture group
    \D*   : any number of non digit char
  )       : end group
$         : end of string

第一个捕获组将匹配所有字符,直到字符串末尾前最后一组数字的第一个数字。

或者如果你可以使用命名组

^(?<prefix>.*?)(?<number>\d+)(?<suffix>\D*)$

【讨论】:

  • 根据最后一组数字的位置,这可能比我的更有效。 +1
  • 好的,这个很好用……但我不知道怎么做!您能否编辑此内容以向 cmets 展示每个人在做什么?例如,即使在你的第一组中,我也很难过......(。*?)......因为我认为问号和星号在一段时间后是互斥的,但显然我错了。
  • 感谢您的解释! :) 非贪婪的东西正是我所需要的!你拿票!谢谢! :)
  • 以前从未见过这种用 记录正则表达式的方法:comment,好主意,谢谢
【解决方案2】:

尝试下一个正则表达式:

(\d+)(?!.*\d)

解释:

(\d+)           # One or more digits.
(?!.*\d)        # (zero-width) Negative look-ahead: Don't find any characters followed with a digit.

编辑(问题的题外话)::此答案不正确,但此问题已在其他帖子中得到解答,因此为避免删除此问题,我将以其他方式使用相同的正则表达式,例如在Perl 中可以这样使用以获得与C# 相同的结果(增加最后一位):

s/(\d+)(?!.*\d)/$1 + 1/e;

【讨论】:

  • 不完全。这确实可以正确识别数字,但它仍然没有显示如何标记字符串以获取前缀和后缀,这也是我最苦恼的。你能帮忙吗?
  • @MarqueIV:你是对的,不是你想要的,我没抓住重点,抱歉。但是现在有一些正确的答案可以很好地解决您的问题。
【解决方案3】:

你也可以试试简单一点的版本:

(\d+)[^\d]*$

【讨论】:

  • 那些其他人不适合我……这可以。简单是一种毒药。
  • 这是一个测试,确认它按预期工作:regex101.com/r/hN8zG5/1
【解决方案4】:

应该这样做:

Regex regexObj = new Regex(@"
    # Grab last set of digits, prefix and suffix.
    ^               # Anchor to start of string.
    (.*)            # $1: Stuff before last set of digits.
    (?<!\d)         # Anchor start of last set of digits.
    (\d+)           # $2: Last set of one or more digits.
    (\D*)           # $3: Zero or more trailing non digits.
    $               # Anchor to end of string.
    ", RegexOptions.IgnorePatternWhitespace);

【讨论】:

    【解决方案5】:

    不使用正则表达式会怎样。这是代码 sn-p(用于控制台)

    string[] myStringArray = new string[] { "abc123def456ghi", "abc123def456ghi789jkl", "abc123def", "123ghi", "abcdef","abc-654def" };
    
            char[] numberSet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
            char[] filterSet = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                                            'n','o','p','q','r','s','t','u','v','w','x','y','z','-'};
            foreach (string myString in myStringArray)
            {
                Console.WriteLine("your string - {0}",myString);
                int index1 = myString.LastIndexOfAny(numberSet);
                if (index1 == -1)
                Console.WriteLine("no number");
                else
                {
                   string mySubString = myString.Substring(0,index1 + 1);
                   string prefix = myString.Substring(index1 + 1);
                   Console.WriteLine("prefix - {0}", prefix);
                   int index2 = mySubString.LastIndexOfAny(filterSet);
                   string suffix = myString.Substring(0, index2 + 1);
                   Console.WriteLine("suffix - {0}",suffix);
                   mySubString = mySubString.Substring(index2 + 1);
                   Console.WriteLine("number - {0}",mySubString);
                   Console.WriteLine("_________________");
                }
            }
            Console.Read();
    

    【讨论】:

      猜你喜欢
      • 2021-07-29
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      • 2018-04-21
      相关资源
      最近更新 更多