regex 一个正则表达式,它匹配任何一个不被另一个正则表达式匹配的单个字符

x3naxklr  于 2023-08-08  发布在  其他
关注(0)|答案(3)|浏览(91)

是否存在这样的正则表达式?为了澄清我的问题,这里有一个例子:
ab将匹配abbacaba,而我想找到的正则表达式将匹配abbacaba
通过实验,我可以看到下面的正则表达式(?!(?=a)ab)(?!(?<=a)b).确实满足上面的表达式,但是如果开始的正则表达式(即我不想匹配的正则表达式)从ab更改为abc,我将不得不重写大部分代码。是否存在更短、更易于移植的替代方案?

tcbh2hod

tcbh2hod1#

你需要the best regex trick(+ (*SKIP)(*FAIL))和一个tempered greedy量词:

(w\hatev[e3]rY0uD()nt\Want\toMatch)
(*SKIP)(*FAIL)
|
(?:(?!(?1)).)+

字符串
(?1)是一个递归模式,它与第一组中包含的表达式匹配。如果你的风格不支持递归,你可以用表达式本身替换它。(*SKIP)(*FAIL)也是如此:如果第一组不是null或类似的,请使用您的语言中的任何内容来放弃比赛。
这比使用w\hatev[e3]rY0uD()nt\Want\toMatch拆分字符串有一些特别的优点。例如,(ab)(*SKIP)(*FAIL)|(?:(?!(?1)).)+匹配以下内容:

ab**bac**ab**a**
abab**cde**ab


试试on regex101.com
由于+只匹配1个或多个字符,因此不需要过滤。另一方面,您的语言的.split()的等价物,如果有的话(I'm looking at you, Lua),通常甚至会返回空字符串。以Python为例:

import re

print(re.split('ab', 'ababcdeab'))  # ['', '', 'cde', '']


如果你想匹配 * 单个 * 字符,只需删除量词:

(w\hatev[e3]rY0uD()nt\Want\toMatch)
(*SKIP)(*FAIL)
|
(?!(?1)).


试试on regex101.com
另一方面,这个把戏可能不值得。为了你的同事,做一个分裂,过滤掉任何你不想要的东西。

eagi6jfj

eagi6jfj2#

一个可能的想法是用正则表达式 * 拆分 * 字符串。然后丢弃匹配的子串并输出剩余的片段。Python的一个例子:

import re

s = 'abbacaba'                  # original string
m = re.split('ab', s)           # split the string on 'ab'
l = [x for x in m if x]         # drop empty elements
print(l)

字符串
输出量:

['bac', 'a']

5f0d552i

5f0d552i3#

可以使用以下结构的正则表达式:

(?<=^|abc)(?:(?!abc).)+

字符串
这里:

  • (?<=^|abc)向后查找,其要求匹配在行的开始处或在abc之后开始,
  • (?!abc)阻止我们的匹配包含abc

请注意,如果您的模式可以是任何正则表达式,则在使用它之前可能需要额外的考虑(例如,反向引用可能会引起麻烦)。
此外,由于初始模式在lookbehind中使用,因此您的引擎可能不支持此解决方案(取决于初始模式)。
例如,PCRE或Python不支持非固定长度的量词(在lookbehind内部),Java不支持无限量词(如+*{2,})。
演示here

相关问题