使用带有转义符的正则表达式进行Java字符串拆分

时间:2019-03-21 07:57:17

标签: java regex string split

我有一个字符串,需要根据定界符(:)进行拆分。该分隔符可以由字符(例如'?')转义。基本上,分隔符可以前面带有任意数量的转义符。考虑下面的示例字符串:

a:b?:c??:d???????:e

在这里,分割后,它应该提供以下字符串列表:

a 
b?:c?? 
d???????:e

基本上,如果定界符(:)前面有偶数个转义字符,则应将其拆分。如果它前面带有奇数个转义字符,则不应拆分。使用正则表达式有解决方案吗? 任何帮助将不胜感激。

之前here也曾提出过类似的问题,但是答案不适用于该用例。

更新: 使用正则表达式((?:\ ?. || [^ :?]))*的解决方案正确分割了字符串。但是,这也很少给出空字符串。如果用+代替*,则即使是真正的空匹配也将被忽略。 (例如:-a :: b仅给出a,b)

1 个答案:

答案 0 :(得分:2)

方案1:没有空匹配项

您可以使用

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

或者,按照链接的答案中的模式

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

请参见this regex demo

详细信息

  • (?:-一个非捕获组的开始
    • \?.-一个?(定界符)后跟任意字符
    • |-或
    • [^:?]-除:(分隔符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'
''

请注意,如果您还希望在字符串的开头/结尾匹配空字符串,请使用(?<![^:])(?![^:])而不是(?<=:)(?=:)