【问题标题】:Regex: How to capture optional group in middle of text?正则表达式:如何在文本中间捕获可选组?
【发布时间】:2016-02-24 04:19:41
【问题描述】:

我正在努力使用正则表达式来捕获一些可选文本 - 它位于一些文件名的中间,但不是全部。最大的问题似乎是我的可选组没有锚定(我在它之前和之后使用.*?)。我仔细查看了过去关于 SO 的答案,但大多数人只有在将可选文本锚定在一侧或另一侧(即在行尾)时才能捕获可选文本。

给定一个文件名列表,我尝试捕获最多 5 件事:

  • 名称:始终存在,文件名中的第一件事
  • NUMBER:始终存在,文件名中的第二项(可能在括号中)
  • 形状:始终存在
  • 颜色:有时存在,但可以出现在形状之前或之后
  • 版本:有时出现,总是最后出现(但后面通常会有垃圾文本)

原文:

name 1111 color shape
name 2222 shape color
name 3333 shape
name (4444) color shape version
name.5555.JUNK.color.JUNK.shape.JUNK.version.JUNK

期望的结果:

name (1111) color shape
name (2222) color shape
name (3333) shape
name (4444) color shape version
name (5555) color shape version

但是当我使用这个正则表达式时:

FIND: (.*?).\(?(\d{4}).*?(color)?.*?(shape).*?(color)?.*?(version)?.*
REPLACE: $1 ($2) $3$5 $4 $6

我明白了:

name (1111)  shape
name (2222)  shape
name (3333)  shape
name (4444)  shape
name (5555)  shape

如您所见,通过将(color)(version) 捕获组设为可选,它根本不会选择它们。 (另外,如果有任何方法可以删除多余的空格,那也很棒。)

顺便说一句,我在每个捕获组之间使用.*?,因为我了解到它是.* 的“懒惰”版本(不是“贪婪”) - 基本上,它尝试尽可能少地匹配尽可能的。如果您是像我这样的正则表达式新手,请在此处了解更多信息:http://www.rexegg.com/regex-quantifiers.html#greedytrap

无论如何,我在这里遗漏了什么非常明显的东西吗?还是没有办法通过正则表达式捕获一些可选文本?

PS。这是我在在线工具上预加载的数据:http://regexr.com/3cs84 - 我知道正则表达式可能会因语言/平台而有所不同,所以如果有什么不同,我最终想在 AppleScript 中使用这个正则表达式进行重命名文件和文件夹(可能通过调用终端命令,因为我认为 AppleScript 本身不支持正则表达式)。

【问题讨论】:

    标签: regex


    【解决方案1】:

    尝试将.*?(foo) 部分放在括号中,如(.*?(foo)),以便? 运算符将.*? 部分考虑在内。

    更正语法(.*?).\(?(\d{4})(.*?(color))?.*?(shape)(.*?(color))?(.*?(version))?.* (example)

    【讨论】:

    • 哦,快,成功了!非常感谢!对于其他看到这个并想知道为什么 regexr.com 的结果与我想要的结果不匹配的人,我只需要对 AlphaDelta 的替换功能进行一次调整:“$1 ($2) $4$7 $5 $9”
    【解决方案2】:

    我对您尝试使用的格式不是特别熟悉,但我相信我想出了一个可以解决您遇到的问题的示例。

    http://regexr.com/3cs8g

    /name ((\([0-9]+\))|([0-9]+)) ((color shape)|(shape( color)?))( version)?/ig
    

    您所描述的是一个可选子句,它可以出现在两个位置之一。所以,你做一个 or 语句来测试每个可能的位置。

    【讨论】:

    • 看起来这适用于我的大多数测试用例,但不适用于我在子句之间有一些“垃圾”文本的地方。不过绝对有帮助,谢谢!
    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多