我是一款商业闭源的Java应用程序的用户,除了它所提供的所有功能外,还可以通过提供正则表达式模式字符串来过滤文本字段。我经常广泛使用这个过滤功能。
我的问题是,我经常发现自己在正则表达式中重复相同的子模式。例如,在这里:
我的问题是,我经常发现自己在正则表达式中重复相同的子模式。例如,在这里:
^(
( # pattern foo
foo_([^_]+)_(windows|linux|osx)
)
|
( # pattern bar
([^_]+)_bar_(windows|linux|osx)_foo_(windows|linux|osx)
)
)$
([^_]+)
和(windows|linux|osx)
这部分经常重复出现。
这只是一个虚构的例子。原始的正则表达式更加复杂,大约大20倍,并且有许多不同的重复。由于重复的子模式大小和数量都在增加,因此它变得有点难以阅读,并且当您尝试修改重复的子模式时,必须同时修改所有重复的子模式,这很麻烦。
所以,我使用regex101进行了一些尝试,并得出了以下结果:
^(
( # a dummy option, defines some frequently used capture groups
(?!x)x # always false, so nothing matches this and the following groups ever
(?'name'[^_]+) # group "name"
(?'os'windows|linux|osx) # group "os"
)
|
( # pattern foo
foo_\g'name'_\g'os'
)
|
( # pattern bar
\g'name'_bar_\g'os'_foo_\g'os'
)
)$
的意思是“保存到regex101网站”。
现在所有子模式都有名称,每当我引用名称时,它们就会被替换为子模式字符串(例如\g'os'
被替换为(windows|linux|osx)
)。名称比相应的子模式短得多,它们也很清晰,只需修改一次子模式即可将修改应用于正则表达式中的所有位置。
这个改进版本的问题在于虽然它是有效的PHP pcre正则表达式,但它是无效的Java正则表达式。除了正则表达式中的注释和错误行之外,Java不支持\g
,如Comparison to Perl 5所述。
在Java Regex中是否有任何方法可以“因式分解”重复的正则表达式模式?别忘了我能做的只是提供一个模式字符串,我无法访问代码。
\g
转义序列来引用命名组,这就是可以解决我的问题的方法,但是Java不支持。我的问题是:我想在Java的正则表达式中实现的内容是否可能? - Cookie Cat