正则表达式用于通过标点符号

时间:2019-05-29 03:29:36

标签: regex

我正在使用:

(.*) CO\s?[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"](.*) 

代表

3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY). 

但是,正则表达式代码不能覆盖第一个单引号。你能告诉我为什么吗?

s/(.*) CO\s?[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"](.*)/$1 CO $2

我希望得到:

3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY)

但我知道

3M CO A'(MINNESOTA MINING AND MANUFACTURING COMPANY)

3 个答案:

答案 0 :(得分:0)

我猜想在这里我们希望设计一个表达式并逐部分匹配我们的输入,例如:

$ VAULT_TOKEN=<Vault_Token> vault token lookup

我们添加了额外的边界,如果不希望的话,可以减少边界。

我们有三个主要的捕获组:

(.+?)\s+CO\s+(['"].+?['"])([(\[{]).+?([)\]}])

RegEx电路

jex.im可视化正则表达式:

enter image description here

DEMO

演示

此代码段仅显示捕获组的工作方式:

(.+?) # anything before Co;
(['"].+?['"]) # the quotation part; and
([(\[{]).+?([)\]}]) # inside various brackets included those, which we can escape, if required.

RegEx

如果不需要此表达式,可以在regex101.com中对其进行修改/更改。

答案 1 :(得分:0)

您的正则表达式应表示为

/(.*)\sCO\s?(\(.+\).*|".+".*|'.+'.*|{.+}.*|\[.+\].*)/
  

(.*)第一个捕获组将捕获起始组(在您的示例中为“ 3M”)

     

\sCO\s然后查找空白,后跟CO,后跟空白

     

(".+".* etc.)第二个捕获组,查找起始引号或方括号,后跟任何字符中的至少一个字符,后跟结束引号,然后是任意数量的任何字符

为什么原始正则表达式不起作用

在原始正则表达式中,[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"]可以简化为[''.*''](对于您提供的字符串)。我意识到,对于其他字符串,您可能希望查找(.*)[.*]{.*}".*",但是对于“ 3M”字符串,仅查找{{1 }}是相关的,所以我们只看一下。

因此[''.*'']的意思是:以任意顺序匹配[''.*'']中列表中的任何字符。在这种情况下,列表中有三个 unique 字符:[]'.(尽管您确实重复了* 3次) 。因此它与第一个'相匹配。但是,由于此匹配项不在您的捕获组'之外,因此第一个()不包括在捕获组响应中。

因此,与'的下一个匹配项将匹配第一个(.*)之后的所有其他内容,并将它们包括在第二个匹配组中,即',前面没有A'(MINNESOTA MINING AND MANUFACTURING COMPANY)

这有意义吗?

演示

如果您想确保格式包括''A'[A]"A"{A},那么您要这样做:

(A)

答案 2 :(得分:0)

'不匹配,因为在第二个捕获组中,因为您使用了可以写为CO\s?[(.*)|[\]{}'"]的字符类,然后它将与CO '

匹配

所以您的模式实际上看起来像:

(.*) CO\s?[.*()|[\]{}'"](.*)
^         ^             ^
group 1   Char class    group 2

要使两组匹配的人可以使用:

(.*?)CO\s?((?:(['"]).*?\3|\(.*?\)|\[.*?\]|\{.*?\}).*)

说明

  • (.*?)捕获组1,匹配除换行符非贪婪以外的任何字符
  • CO\s?匹配CO和可选的空白字符
  • (捕获组2
    • (?:非捕获组,匹配任何选项
      • (['"]).*?\3匹配“或”,并使用反向引用捕获的内容
      • |
      • \(.*?\)匹配( .... )
      • |
      • \[.*?\]匹配[ .... ]
      • |
      • \{.*?\}匹配{ .... }
    • )关闭非捕获组
    • .*匹配所有字符,直到字符串末尾
  • )关闭第2组

Regex demo

请注意,.*?不贪婪,以防止不必要的回溯和过度匹配。