正则实现:若下一个A出现前无字符串B则捕获当前A
问题解答
这个需求完全可以通过正则表达式实现,核心借助零宽断言即可完成,不需要额外的文本处理逻辑。
可用正则表达式
如果你的待匹配文本是单行内容,直接使用以下正则,开启全局匹配模式(g)即可拿到所有符合要求的A:
A(?=(?:(?!A|B).)*(?:A|$))
如果需要匹配跨换行的多行文本,要么开启正则的单行(dotAll,即s)模式让.可以匹配换行符,要么直接将表达式中的.替换为[\s\S]来兼容所有字符,写法如下:
A(?=(?:(?!A|B)[\s\S])*(?:A|$))
匹配逻辑说明
- 表达式最开头的
A就是我们要找的目标字符/字符串 - 后续的
(?=...)是正向零宽先行断言,仅校验A后面的内容是否符合规则,不会消费字符,不会打断后续的全局匹配流程 - 断言内部的
(?:(?!A|B).)*负责从当前A的下一个位置开始向后遍历:每匹配一个字符前,都先确认当前位置不是A也不是B的起点,直到碰到A、B或者字符串结尾才停止遍历 - 遍历停止后,要求接下来遇到的必须是下一个A,或者直接到达字符串结尾
$:如果停止时遇到的是B,就说明当前A和下一个A(或字符串末尾)之间存在B,不符合规则,这个A就不会被匹配。
示例匹配验证
你给出的几个测试用例,用上述正则匹配的结果和标注完全一致:
- 用例
A something A something B:第一个A向后遍历到下一个A时都未碰到B,命中;第二个A向后遍历时先碰到B,不命中,仅第一个A符合要求 - 用例
AAAB:第一个A后紧跟第二个A,中间无B,命中;第二个A后紧跟第三个A,中间无B,命中;第三个A后先碰到B,不命中,共前两个A符合要求 - 用例
ABAAB:第一个A后先碰到B,不命中;位于第三个字符位置的A后紧跟下一个A,中间无B,命中;最后一个A后先碰到B,不命中,仅标注位置的A符合要求 - 用例
A B A something:第一个A后先碰到B,不命中;位于第四个字符位置的A向后一直遍历到字符串结尾都未碰到A或B,命中,和标注结果一致
如果你的A、B不是单个字符,而是更长的固定字符串或复杂匹配规则,只需要把正则里对应位置的A、B替换成对应的子模式即可,比如要匹配的A是start、B是end,正则可调整为start(?=(?:(?!start|end)[\s\S])*(?:start|$))。
内容的提问来源于stack exchange,提问作者Crimsoon
相关产品推荐
相关产品推荐

