Regex 传递标点符号的正则表达式

Regex 传递标点符号的正则表达式,regex,Regex,我正在使用: (.*) CO\s?[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"](.*) 代表 3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY). 但是,正则表达式代码不能包含第一个单引号。你能告诉我为什么吗 s/(.*) CO\s?[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"](.*)/$1 CO $2 我希望得到: 3M CO 'A'(MINNESOTA MINING AND MA

我正在使用:

(.*) 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)

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

(.+?)\s+CO\s+(['"].+?['"])([(\[{]).+?([)\]}])
我们增加了额外的边界,如果不需要,可以减少

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

(.+?) # anything before Co;
(['"].+?['"]) # the quotation part; and
([(\[{]).+?([)\]}]) # inside various brackets included those, which we can escape, if required.
正则表达式电路 可视化正则表达式:

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

const regex=/(.+?)\s+CO\s+([''''].+?[''']])([(\[{].+?([)\]}])/mg;
const str=`3M公司'A'(明尼苏达州采矿和制造公司)
3M公司【明尼苏达州采矿和制造公司】
3M公司{明尼苏达州采矿和制造公司}
3M公司是明尼苏达州采矿和制造公司;
让m;
while((m=regex.exec(str))!==null){
//这是避免具有零宽度匹配的无限循环所必需的
if(m.index==regex.lastIndex){
regex.lastIndex++;
}
//可以通过'm`-变量访问结果。
m、 forEach((匹配,组索引)=>{
log(`Found match,group${groupIndex}:${match}`);
});

}
您的正则表达式应该表示为

/(.*)\sCO\s?(\(.+\).*|".+".*|'.+'.*|{.+}.*|\[.+\].*)/
(.*)
第一个捕获组将捕获起始组(在您的示例中为“3M”)

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

(“+”*等)
第二个捕获组,用于查找起始引号或括号,后跟任何内容的至少一个字符,后跟结束引号,然后后跟任意数量的任何字符

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

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

所以
['.*']
的意思是:以任何顺序匹配
[]
中列表中的任何字符。在本例中,列表中有三个唯一的字符:
'
*
(尽管您重复了
'
三次)。所以它匹配了第一个
。但由于此匹配不在您的捕获组
()
,因此第一个
不包括在您的捕获组响应中

因此,与
(.*)
的下一个匹配匹配第一个
之后的所有其他匹配项,并将它们包含在第二个匹配组中,即
A”(明尼苏达采矿和制造公司)
,前面没有

这有意义吗

演示

如果您想确保格式包括
'A'
[A]
“A”
{A}
(A)
,那么这就是您想要的:

let regex=/(.*)\sCO\s?(\(.+\)\+.*.+.*.+.*.*.{.+}.*.[.+\].*)/;
[pattern,match1,match2]=“3M公司(明尼苏达州采矿和制造公司)”。match(regex);
控制台日志(匹配1+“CO”+匹配2);
//3M公司(明尼苏达州采矿和制造公司)
[pattern,match1,match2]=“3M公司(明尼苏达州采矿和制造公司)”。match(regex);
控制台日志(匹配1+“CO”+匹配2);
//3M公司(A)(明尼苏达州采矿和制造公司)
[pattern,match1,match2]=“3M公司”(明尼苏达州采矿和制造公司)匹配(regex);
控制台日志(匹配1+“CO”+匹配2);
//3M公司“A”(明尼苏达州采矿和制造公司)
[pattern,match1,match2]=“3M公司(明尼苏达州采矿和制造公司)”。匹配(regex);
控制台日志(匹配1+“CO”+匹配2);
//3M公司[A](明尼苏达州采矿和制造公司)
[pattern,match1,match2]=“3M公司(明尼苏达采矿和制造公司)”.match(regex);
控制台日志(匹配1+“CO”+匹配2);

//3M CO{A}(明尼苏达采矿和制造公司)
第二个捕获组中的
'
不匹配,因为您使用的字符类可以写成
CO\s?[(.*)[\]{}]
,然后它将匹配
CO'

因此,您的模式实际上看起来像:

(.*) CO\s?[.*()|[\]{}'"](.*)
^         ^             ^
group 1   Char class    group 2
要将这些匹配分为两组,您可以使用:

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

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


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

如果您将鼠标悬停在
regex
标记上,您会注意到它要求您提供更多信息(即您在中使用regex的语言/程序)。