我有一个字符串,需要根据定界符(:)进行拆分。该分隔符可以由字符(例如'?')转义。基本上,分隔符可以前面带有任意数量的转义符。考虑下面的示例字符串:
a:b?:c??:d???????:e
在这里,分割后,它应该提供以下字符串列表:
a
b?:c??
d???????:e
基本上,如果定界符(:)前面有偶数个转义字符,则应将其拆分。如果它前面带有奇数个转义字符,则不应拆分。使用正则表达式有解决方案吗? 任何帮助将不胜感激。
之前here也曾提出过类似的问题,但是答案不适用于该用例。
更新: 使用正则表达式((?:\ ?. || [^ :?]))*的解决方案正确分割了字符串。但是,这也很少给出空字符串。如果用+代替*,则即使是真正的空匹配也将被忽略。 (例如:-a :: b仅给出a,b)
答案 0 :(得分:2)
方案1:没有空匹配项
您可以使用
(?:\?.|[^:?])+
或者,按照链接的答案中的模式
(?:\?.|[^:?]++)+
详细信息
(?:
-一个非捕获组的开始
\?.
-一个?
(定界符)后跟任意字符|
-或[^:?]
-除:
(分隔符char)和?
(转义字符)之外的任何字符)+
-1次或多次重复。在Java中:
String regex = "(?:\\?.|[^:?]++)+";
如果输入中包含换行符,请在模式前加上(?s)
(例如(?s)(?:\\?.|[^:?])+
)或使用Pattern.DOTALL
标志编译模式。
方案2:包括空匹配项
您可以为上述模式添加(?<=:)(?=:)
替代项,以匹配:
个字符之间的空字符串,请参见this regex demo:
String s = "::a:b?:c??::d???????:e::";
Pattern pattern = Pattern.compile("(?>\\?.|[^:?])+|(?<=:)(?=:)");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
System.out.println("'" + matcher.group() + "'");
}
Java demo的输出:
''
'a'
'b?:c??'
''
'd???????:e'
''
请注意,如果您还希望在字符串的开头/结尾匹配空字符串,请使用(?<![^:])(?![^:])
而不是(?<=:)(?=:)
。