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})'