代码之家  ›  专栏  ›  技术社区  ›  Tamas Czinege

跳过捕获组中字符的正则表达式

  •  33
  • Tamas Czinege  · 技术社区  · 16 年前

    在正则表达式中,是否可以跳过捕获组中的几个字符?我正在使用.NET正则表达式,但这不重要。

    基本上,我要找的是:

    [随机文本]AB-123[随机文本]

    我需要捕捉“ab123”,没有连字符。

    我知道ab是2或3个大写字符,123是2或3个数字,但这不是最难的部分。最难的部分(至少对我来说)是跳过连字符。

    我想我可以分别捕获它们,然后将它们连接到代码中,但我希望我有一个更优雅的、仅限regex的解决方案。

    有什么建议吗?

    5 回复  |  直到 7 年前
        1
  •  42
  •   Tomalak    16 年前

    简而言之:你不能。一个匹配总是连续的,即使它包含零宽度断言,如果你想在下一个字符之后找到它,也没有办法匹配下一个字符。

        2
  •  16
  •   Jeff Hillman    16 年前

    实际上没有一种方法可以创建这样一个表达式:匹配的文本与源文本中的文本不同。您需要在单独的步骤中删除连字符,方法是单独匹配第一部分和第二部分,并连接两个组:

    match = Regex.Match( text, "([A-B]{2,3})-([0-9]{2,3})" );
    matchedText = string.Format( "{0}{1}", 
        match.Groups.Item(1).Value, 
        match.Groups.Item(2).Value );
    

    或者在与匹配过程分开的步骤中删除连字符:

    match = Regex.Match( text, "[A-B]{2,3}-[0-9]{2,3}" );
    matchedText = match.Value.Replace( "-", "" );
    
        3
  •  4
  •   Kent Fredric    16 年前

    您的断言,如果不使用子分组+具体化它是不可能做到的,这是正确的。

    你也可以像杰夫·希尔曼那样,只需在事后揭穿坏人。

    这里要注意的重要一点是,你“不要用regex做任何事情”。

    regex是为解决非平凡的问题而设计的,你不应该用“哦,我们会用regex”来解决所有问题,你不应该认为你可以用一步regex来解决问题。

    当有一个可行的琐碎方法,无论如何都能奏效时,使用它。

    另一种想法是,如果您碰巧需要在代码体中返回多个匹配项,请查找基于语言“回调”的regex,它允许将任何匹配/找到的组传递给可以进行内联替换的函数调用。(尤其是在做regexp替换时非常方便)。

    不确定它在.NET中是如何工作的,但在PHP中,您可以执行类似的操作(不是精确的代码)。

      function strip_reverse( $a )
      {
         $a = preg_replace("/-/", "", $a );
         return reverse($a);
      }
      $b = preg_replace_callback( "/(AB[-]?cde)/" , 'strip_reverse' , "Hello World AB-cde" ; 
    
        4
  •  1
  •   Alan Moore Chris Ballance    9 年前

    可以使用嵌套的捕获组,如下所示:

    ((AB)-(123))
    

    第一个捕获组是 AB-123 第二个是 AB 第三个是 123 . 那么你所要做的就是加入第二组和第三组。

        5
  •  0
  •   LW001 Rohan Muhammad    7 年前

    有点晚了,但我想我已经弄明白了。至少有一种方法可以做到。

    我用积极的期待停在我的文本中的标志。我不想要这个空间或标志,所以我不得不想办法“跳过”它们。所以当我被迫再次匹配它们时,我把它们扔到了一个垃圾组中,而我并没有打算使用(.ie,一个比特桶),在代码中就是这样。现在,我的位置指针是在符号之外的一个字符位置(在我想要的位置,跳过空格和符号)。我现在只匹配文件名的结尾。忽略文件扩展名。

    (?i)English\\(?<Series>[^ ]+) - (?<Title>.+(?= #))(?<garb1>..)(?<Number>[^.]+)(?-i)
    

    使用的文件名是

    F:\Downloads\Downloads\500 Comics CCC CBR English\Isukani - Great Girl #01.cbr