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和可选空格字符CO\s?
捕获组2(
非捕获组,匹配任何选项(?:
匹配“或”,并使用对捕获内容的反向引用(['“]).*?\3
或|
匹配\(.*?\)
…(
)
或|
匹配\[.*?\]
…[
]
或|
匹配\{.*?\}
…{
}
关闭非捕获组)
匹配任何字符,直到字符串结束*
关闭第2组)
请注意,
*?
是非贪婪的,以防止不必要的回溯和过度匹配。如果您将鼠标悬停在regex
标记上,您会注意到它要求您提供更多信息(即您在中使用regex的语言/程序)。