如何简化正则表达式模式?
How to simplify a regex pattern?
我在这里试图简化正则表达式。
我尝试对同一个表达式进行重复,但是当我尝试使用 ()* 简化它时,它不起作用,因为它没有检测到我想要的模式。
这些是我的正则表达式:
(([\(]\w]{1,3}[\)])\s([\d]{1,3}[\?])([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]([\(][\w]{1,3}[\)])\s([\d]{1,3}[\?])([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]([\(][\w]{1,3}[\)])\s[0-9]{1,3}[\?]([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?])
整个模式:
3A 1?(1) 2?(2) 3?(a) 4?(4) 5?(a) 6?(ii) 7?
4 6?(1) 7?(2) 8?(a) 9?(4) 10?(a) 11?(ii) 12?
这些是它将检测到的模式:
1?(1) 2?(2) 3?(a) 4?(4) 5?(a) 6?(ii) 7?
正则表达式将检测 ONLY first LINE 而没有 3A。我该怎么做?
正则表达式已经是最简单的 \d+\?(?:\([\da-z]+\))?
,现在我怎样才能把它放在一种只检测 第一行 的方式中?谢谢大家。
也许,如果可能的话,我们可以用另一种方式简化它。例如,我们可能有三个模式,我们可以使用三个捕获组来捕获它:开始、结束和中间组,可能类似于:
(?:^\w+\s)|(\d\?\(\w+\)\s)|(?:\d+\?$)
正则表达式
如果这不是您想要的表达式,您可以 modify/change 在 regex101.com 中添加您的表达式,并根据需要添加或减少边界。
正则表达式电路
您还可以在 jex.im:
中可视化您的表情
JavaScript 捕获组演示
const regex = /(?:^\w+\s)|(\d\?\(\w+\)\s)|(?:\d+\?$)/gm;
const str = `3A 4?(1) 5?(2) 6?(a) 7?(4) 8?(a) 9?(ii) 10?`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
此模式 ([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]
与前导 4?
不匹配
您可以通过删除方括号来简化表达式,因为您不需要它们并添加一个可选部分以匹配前面带问号的 1-3 位数字:
(?:\d{1,3}\?)?(\(\w{1,3}\))\s\d{1,3}\?
如果您不想要单独的匹配,而是 1 个单独的匹配,并且数字问号部分也可以在括号之间没有以下部分的情况下出现,您可以使用一个重复组和一个可选部分作为括号:
\d+\?(?:\(\w{1,3}\))?(?: \d+\?(?:\(\w{1,3}\))?)+
说明
\d+\?
匹配1+个数字和?
(?:\(\w{1,3}\))?
匹配括号部分的可选组
(?:
非捕获组
\d+\?(?:\(\w{1,3}\))?
匹配 1+ 个数字和 ?
后跟括号的可选部分
)+
关闭非捕获组并重复1+次
备注
在您的示例的第一个模式中缺少左括号
(([\(][\w]{1,3}
^
在第二个表达式中,模式末尾有一个右括号 )
。
试试这个模式:\d+\?(?:\([\da-z]+\))?
解释:
\d+
- 匹配一位或多位数字
\?
- 按字面意思匹配 ?
(?:...)
- non-capturing组
\(
- 按字面意思匹配 (
[\da-z]+
- 匹配一个或多个数字或小写字母
\)
- 按字面意思匹配 )
?
- 最多匹配一次前面的模式,即 \([\da-z]+\)
代码中的用法:
Sub Main()
Dim matches = Regex.Matches("3A 4?(1) 5?(2) 6?(a) 7?(4) 8?(a) 9?(ii) 10?", "\d+\?(?:\([\da-z]+\))?")
For Each match As Match In matches
Console.WriteLine(match.Value)
Next
Console.ReadKey()
End Sub
更新:
尝试更新模式:^(?:\d+(?:\?(?:\([\da-z]+\))?|[A-Z]+) ?)+$
我在这里试图简化正则表达式。
我尝试对同一个表达式进行重复,但是当我尝试使用 ()* 简化它时,它不起作用,因为它没有检测到我想要的模式。
这些是我的正则表达式:
(([\(]\w]{1,3}[\)])\s([\d]{1,3}[\?])([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]([\(][\w]{1,3}[\)])\s([\d]{1,3}[\?])([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]([\(][\w]{1,3}[\)])\s[0-9]{1,3}[\?]([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?])
整个模式:
3A 1?(1) 2?(2) 3?(a) 4?(4) 5?(a) 6?(ii) 7?
4 6?(1) 7?(2) 8?(a) 9?(4) 10?(a) 11?(ii) 12?
这些是它将检测到的模式:
1?(1) 2?(2) 3?(a) 4?(4) 5?(a) 6?(ii) 7?
正则表达式将检测 ONLY first LINE 而没有 3A。我该怎么做?
正则表达式已经是最简单的 \d+\?(?:\([\da-z]+\))?
,现在我怎样才能把它放在一种只检测 第一行 的方式中?谢谢大家。
也许,如果可能的话,我们可以用另一种方式简化它。例如,我们可能有三个模式,我们可以使用三个捕获组来捕获它:开始、结束和中间组,可能类似于:
(?:^\w+\s)|(\d\?\(\w+\)\s)|(?:\d+\?$)
正则表达式
如果这不是您想要的表达式,您可以 modify/change 在 regex101.com 中添加您的表达式,并根据需要添加或减少边界。
正则表达式电路
您还可以在 jex.im:
中可视化您的表情JavaScript 捕获组演示
const regex = /(?:^\w+\s)|(\d\?\(\w+\)\s)|(?:\d+\?$)/gm;
const str = `3A 4?(1) 5?(2) 6?(a) 7?(4) 8?(a) 9?(ii) 10?`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
此模式 ([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]
与前导 4?
您可以通过删除方括号来简化表达式,因为您不需要它们并添加一个可选部分以匹配前面带问号的 1-3 位数字:
(?:\d{1,3}\?)?(\(\w{1,3}\))\s\d{1,3}\?
如果您不想要单独的匹配,而是 1 个单独的匹配,并且数字问号部分也可以在括号之间没有以下部分的情况下出现,您可以使用一个重复组和一个可选部分作为括号:
\d+\?(?:\(\w{1,3}\))?(?: \d+\?(?:\(\w{1,3}\))?)+
说明
\d+\?
匹配1+个数字和?
(?:\(\w{1,3}\))?
匹配括号部分的可选组(?:
非捕获组\d+\?(?:\(\w{1,3}\))?
匹配 1+ 个数字和?
后跟括号的可选部分
)+
关闭非捕获组并重复1+次
备注
在您的示例的第一个模式中缺少左括号
(([\(][\w]{1,3}
^
在第二个表达式中,模式末尾有一个右括号 )
。
试试这个模式:\d+\?(?:\([\da-z]+\))?
解释:
\d+
- 匹配一位或多位数字
\?
- 按字面意思匹配 ?
(?:...)
- non-capturing组
\(
- 按字面意思匹配 (
[\da-z]+
- 匹配一个或多个数字或小写字母
\)
- 按字面意思匹配 )
?
- 最多匹配一次前面的模式,即 \([\da-z]+\)
代码中的用法:
Sub Main()
Dim matches = Regex.Matches("3A 4?(1) 5?(2) 6?(a) 7?(4) 8?(a) 9?(ii) 10?", "\d+\?(?:\([\da-z]+\))?")
For Each match As Match In matches
Console.WriteLine(match.Value)
Next
Console.ReadKey()
End Sub
更新:
尝试更新模式:^(?:\d+(?:\?(?:\([\da-z]+\))?|[A-Z]+) ?)+$