我有一个字符串需要根据分隔符(:) 进行分割。该分隔符可以通过字符转义(例如“?”)。基本上,分隔符前面可以有任意数量的转义字符。考虑下面的示例字符串:
a:b?:c??:d???????:e
这里,分割后,它应该给出以下字符串列表:
a
b?:c??
d???????:e
基本上,如果分隔符 (:) 前面有偶数个转义字符,则应将其拆分。如果它前面有奇数个转义字符,则不应分割它。有正则表达式解决这个问题吗? 任何帮助将不胜感激。
之前已提出过类似问题here ,但答案不适用于此用例。
更新: 使用正则表达式的解决方案: (?:\?.|[^:?])* 正确分割了字符串。然而,这也给出了很少的空字符串。如果给出+而不是*,即使是真正的空匹配也会被忽略。 (例如:- a::b 仅给出 a,b)
最佳答案
场景 1:没有空匹配
您可以使用
(?:\?.|[^:?])+
或者,按照链接答案中的模式进行操作
(?:\?.|[^:?]++)+
详细信息
-
(?:
- 非捕获组的开始-
\?.
- 一个?
(分隔符)后跟任何字符 -
|
- 或 -
[^:?]
- 除:
之外的任何字符(您的分隔符)和?
(转义字符)
-
-
)+
- 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'
''
注意,如果您还想匹配字符串开头/结尾处的空字符串,请使用 (?<![^:])(?![^:])
而不是(?<=:)(?=:)
.
关于使用带有转义字符的正则表达式分割 Java 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55275918/