如何使用Regex将A组的字符编号与B组的字符数相匹配

  • 本文关键字:字符 编号 Regex 何使用 regex
  • 更新时间 :
  • 英文 :


例如,我想匹配如下模式:

  1. AAAB
  2. AAABB
  3. AAB

与以下模式不匹配:

  1. AAABBBB
  2. ABB
  3. 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(

最新更新