是否存在这样的正则表达式?为了澄清我的问题,这里有一个例子:ab将匹配abbacaba,而我想找到的正则表达式将匹配abbacaba。通过实验,我可以看到下面的正则表达式(?!(?=a)ab)(?!(?<=a)b).确实满足上面的表达式,但是如果开始的正则表达式(即我不想匹配的正则表达式)从ab更改为abc,我将不得不重写大部分代码。是否存在更短、更易于移植的替代方案?
ab
(?!(?=a)ab)(?!(?<=a)b).
abc
tcbh2hod1#
你需要the best regex trick(+ (*SKIP)(*FAIL))和一个tempered greedy量词:
(*SKIP)(*FAIL)
(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)).)+匹配以下内容:
(?1)
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为例:
+
.split()
import re print(re.split('ab', 'ababcdeab')) # ['', '', 'cde', '']
型如果你想匹配 * 单个 * 字符,只需删除量词:
(w\hatev[e3]rY0uD()nt\Want\toMatch) (*SKIP)(*FAIL) | (?!(?1)).
型试试on regex101.com。另一方面,这个把戏可能不值得。为了你的同事,做一个分裂,过滤掉任何你不想要的东西。
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']
型
5f0d552i3#
可以使用以下结构的正则表达式:
(?<=^|abc)(?:(?!abc).)+
字符串这里:
(?<=^|abc)
(?!abc)
请注意,如果您的模式可以是任何正则表达式,则在使用它之前可能需要额外的考虑(例如,反向引用可能会引起麻烦)。此外,由于初始模式在lookbehind中使用,因此您的引擎可能不支持此解决方案(取决于初始模式)。例如,PCRE或Python不支持非固定长度的量词(在lookbehind内部),Java不支持无限量词(如+,*或{2,})。演示here。
*
{2,}
3条答案
按热度按时间tcbh2hod1#
你需要the best regex trick(+
(*SKIP)(*FAIL)
)和一个tempered greedy量词:字符串
(?1)
是一个递归模式,它与第一组中包含的表达式匹配。如果你的风格不支持递归,你可以用表达式本身替换它。(*SKIP)(*FAIL)
也是如此:如果第一组不是null
或类似的,请使用您的语言中的任何内容来放弃比赛。这比使用
w\hatev[e3]rY0uD()nt\Want\toMatch
拆分字符串有一些特别的优点。例如,(ab)(*SKIP)(*FAIL)|(?:(?!(?1)).)+
匹配以下内容:型
试试on regex101.com。
由于
+
只匹配1个或多个字符,因此不需要过滤。另一方面,您的语言的.split()
的等价物,如果有的话(I'm looking at you, Lua),通常甚至会返回空字符串。以Python为例:型
如果你想匹配 * 单个 * 字符,只需删除量词:
型
试试on regex101.com。
另一方面,这个把戏可能不值得。为了你的同事,做一个分裂,过滤掉任何你不想要的东西。
eagi6jfj2#
一个可能的想法是用正则表达式 * 拆分 * 字符串。然后丢弃匹配的子串并输出剩余的片段。Python的一个例子:
字符串
输出量:
型
5f0d552i3#
可以使用以下结构的正则表达式:
字符串
这里:
(?<=^|abc)
向后查找,其要求匹配在行的开始处或在abc
之后开始,(?!abc)
阻止我们的匹配包含abc
。请注意,如果您的模式可以是任何正则表达式,则在使用它之前可能需要额外的考虑(例如,反向引用可能会引起麻烦)。
此外,由于初始模式在lookbehind中使用,因此您的引擎可能不支持此解决方案(取决于初始模式)。
例如,PCRE或Python不支持非固定长度的量词(在lookbehind内部),Java不支持无限量词(如
+
,*
或{2,}
)。演示here。