例如,我想匹配如下模式:
- AAAB
- AAABB
- AAB
与以下模式不匹配:
- AAABBBB
- ABB
- AABBB
如上所述,字符B的出现次数应少于字符A。
请考虑在匹配后比较组长度,而不是直接在正则表达式中区分组长度!
Python中的示例:
for test_string in collection_of_strings:
match = re.match(RE_myregex, test_string)
if not match: # regex did not match at all
continue # jump to top of loop to try next string
a, b = match.groups() # unpack match groups
if len(b) >= len(a): # must be fewer B than A
continue
# work with a and b
可能最好只使用模式长度并像@ti7那样进行比较。
可以使用regex,但是regex没有可变长度反向引用的概念。尽管如此,你可以先做两个A的测试,然后是3个A,然后是4个A,达到你需要的水平。下面是一个测试多达4个As的JavaScript示例。作为奖励,它测试任何类型的字符序列,然后是任何其他字符序列:
const input =[
'AAB',
'AABB',
'AABBB',
'AAAB',
'AAABB',
'AAABBB',
'AAABBBB',
'AAAAB',
'AAAABB',
'AAAABBB',
'AAAABBBB',
'AAAAAB',
'AAAAABB',
'AAAAABBB',
'AAAAABBBB',
'AAAAABBBBB',
];
const regex = /^(?:(.)1(?![^1]{2})|(.)22(?![^2]{3})|(.)333(?![^3]{4})|(.)4444(?![^4]{5}))/;
input.forEach(str => {
console.log(str + ' => ' + regex.test(str));
});
输出:
AAB => true
AABB => false
AABBB => false
AAAB => true
AAABB => true
AAABBB => false
AAABBBB => false
AAAAB => true
AAAABB => true
AAAABBB => true
AAAABBBB => false
AAAAAB => true
AAAAABB => true
AAAAABBB => true
AAAAABBBB => true
AAAAABBBBB => false
正则表达式的解释:
(?:
。。。|
。。。|
。。。|
…(-非捕获OR组(.)1(?![^1]{2})
:(.)
捕获任何字符1
再次期望相同的字符(?![^1]{2})
-之前不匹配的两个相同字符的负前瞻
(.)22(?![^2]{3})
:(.)
捕获任何字符(第二个捕获组(22
期望再次出现相同的字符(?![^2]{3})
-之前不匹配的三个相同字符的否定前瞻
- 漂洗&根据需要重复多次
PCRE兼容引擎的基于正则表达式的解决方案。(应该支持子程序和查找(。
模式确实有点复杂,正如其他答案中提到的,自定义代码可能是您场景的正确选择。
方法:
- 匹配第一个"A">
- Postthat在递归中,每个
A
可以与一个B
配对
演示:https://regex101.com/r/n6IFQ9/6
模式:
^(?'r'(.)
(?>(?=2)(?&r)(.|$)(?=3|$)
|)
)$
细分:
(?'r'...)
:定义一个名为r
的子例程(.)
:匹配任意字符。在组2
中捕获(?=2)(?&r)(.|$)(?=3|$)
:下一个字符与当前字符匹配。(?=2)
:"正向前瞻"检查下一个字符是否与2
匹配。(在第一个B
之前为True((?&r)
:调用子程序r
。(递归((.|$)(?=3|$)
:这将在递归后匹配。- 匹配
.
或$
并在3
中捕获它 - 它后面应该是
3
或$
- 匹配
- 或返回成功(对于第一个
B
(