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

时间:2017-06-02 13:55:36

标签: java regex

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

ABC??'DEF?'GHI'JKL????'MNO'

会导致:

ABC??
DEF?'GHI
JKL????
MNO

我尝试过使用这种负面的背后隐藏:

(?<!\?\?)*\'

但结果是:

ABC??
DEF?
GHI
JKL????
MNO

我也试过以下

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

非常感谢任何想法。

4 个答案:

答案 0 :(得分:0)

你有没有尝试过积极的背后隐藏

(小于?=')

Regex101

答案 1 :(得分:0)

这个正则表达式会这样做:

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

答案 2 :(得分:0)

在这种情况下使用split方法并不方便。解决方法包括描述所有不是分隔符并使用find方法:

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

demo

模式细节:

[^?']*     # 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

[^?']*(?:\?.[^?']*)*描述了所有不是包含空字符串的分隔符。为了避免空匹配,我使用了一个交替的2个分支:[^?']+(?:\?.[^?']*)*(?:\?.[^?']*)+来确保至少有一个字符。

(如果您想在字符串的开头允许空字符串,请在模式的末尾添加|^

您也可以使用split方法,但是执行此操作的模式效率不高,因为它需要向后查找每个位置(并且由于java中的lookbehind只允许有限的量词,因此受限制)

(?<=(?<!\?)(?:\?\?){0,100})'

或者像这样效率更高:

'(?<=(?<!\?)(?:\?\?){0,100}')

答案 3 :(得分:0)

如果需要处理一个问号,而不是三个,五个等,你可以使用它:

(?<![^\?]\?)'

您可以扩展此概念以匹配其他特定奇数的问号。例如,这将在一个,三个或五个问号前面的引号中正确分割:

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

Working example。 Lookbehinds必须是固定宽度的,但是一些引擎允许整个lookbehind的OR。其他人没有,并且要求将其写成三个独立的外观:

(?<![^\?]\?)(?<![^\?]\?{3})(?<![^\?]\?{5})'
但是,显然这会变得有些混乱。并且它无法处理任意奇数?。