Java 正则表达式在前面的偶数个字符上拆分字符串

Java 正则表达式在前面的偶数个字符上拆分字符串,java,regex,Java,Regex,我正在尝试开发一个正则表达式,只有在单引号前面有零个问号或偶数个问号时,它才会在单引号上拆分字符串。例如,以下字符串: ABC??'DEF?'GHI'JKL????'MNO' 将导致: ABC?? DEF?'GHI JKL???? MNO 我尝试过使用这种消极的回顾: (?<!\?\?)*\' 我也试过以下方法 (?<!(\?\?)*)\' results in runtime error (?:\?\?)*\' (?!\?\?)+\' (? 如果您有任何想法,我们将不胜感

我正在尝试开发一个正则表达式,只有在单引号前面有零个问号或偶数个问号时,它才会在单引号上拆分字符串。例如,以下字符串:

ABC??'DEF?'GHI'JKL????'MNO'
将导致:

ABC??
DEF?'GHI
JKL????
MNO
我尝试过使用这种消极的回顾:

(?<!\?\?)*\'
我也试过以下方法

(?<!(\?\?)*)\'  results in runtime error
(?:\?\?)*\'
(?!\?\?)+\'
(?

如果您有任何想法,我们将不胜感激。

您是否尝试过积极的回头看

(?此正则表达式将执行以下操作:

[A-Z]+(\?\?)*'

在这种情况下使用拆分方法并不方便。解决方法包括描述所有非分隔符的内容,以及使用
find
方法:

[^?']+(?:\?.[^?']*)*|(?:\?.[^?']*)+

图案详情:

[^?']*     # zero or more characters that aren't a `?` or a `'`
(?:        # open a non-capturing group
    \? .   # a question mark followed by a character (that can be a `?` or a `'`)
    [^?']* # 
)*         # close the non-capturing group and repeat it zero or more times
[^?']*(?:\?[^?']*)*
描述了所有非分隔符的内容,包括空字符串。为了避免空匹配,我使用了两个可选分支:
[^?']+(?:\?[^?']*)*
(?:\?[^?']*)+
,以确保至少有一个字符

(如果要允许在字符串开头使用空字符串,请在模式末尾添加
|^


您也可以使用split方法,但执行该方法的模式效率不高,因为它需要向后查看每个位置(并且受到限制,因为java中的lookback只允许有限的量词):


(?如果您只需要处理一个问号,而不是三个、五个等,您可以使用以下方法:

(?<![^\?]\?)'
(?
.lookbehind必须为固定宽度,但某些引擎允许对整个lookbehind进行OR。其他引擎则不允许,并要求将其写为三个单独的lookbehind:

(?<![^\?]\?)(?<![^\?]\?{3})(?<![^\?]\?{5})'

(?量词和lookaround不太喜欢对方。我相信Java只允许您使用?和{}在lookaround中,许多语言甚至不允许这样做。我怀疑一个正则表达式可以做到这一点。有没有理由你不能编写几行代码来完成这一点,而不是编写一个单独的
拆分
调用?@tsleyson仅用于lookbehinds,对于lookaheads,你可以使用
*
@dognose。我已经忘记了,谢谢。现在它与som匹配了ewhat如预期,但仍包括
[A-Z]+模式中的
会在拆分时删除它们,这是不需要的。拆分应该只在
上进行,因此没有lookarounds是不可能的,因为它们是非消耗性的。@dognose,这是正确的。因为我需要保留?号,所以我必须使用lookarounds.Casimir,正如您建议的那样…使用find().你能解释一下正则表达式吗?@ShawnGeraghty:这并不复杂,我会补充更多细节。
'(?<=(?<!\?)(?:\?\?){0,100}')
(?<![^\?]\?)'
(?<![^\?]\?|[^\?]\?{3}|[^\?]\?{5})'
(?<![^\?]\?)(?<![^\?]\?{3})(?<![^\?]\?{5})'