Java Regex/Split 不丢字

Java Regex/Split without lose characters

我有这个字符串:

String str = "Filtración con membrana - Nanofiltración Ósmosis inversa Desinfección";

我想得到一个包含这些元素的数组:

["Filtración con membrana - Nanofiltración", "Osmosis inversa", "Desinfección"]

我是这样拆分的:

String[] elements = str.split("[a-zà-ú] [A-ZÀ-Ú]");

但我得到的是这个数组:

["Filtración con membrana - Nanofiltració", "osmosis invers", "esinfección"]

我能做什么?我只想删除拆分中的 space (" ") 而不是字符。谢谢!

为什么 [a-zà-ú] [A-ZÀ-Ú] 不起作用?

正则表达式的问题是 space 两侧的字符 classes 将各占用一个字符。所以 split 函数确实会带走与正则表达式匹配的那两个字符,并且不会包含在输出中

解决方案

与其使用正则表达式,不如尝试环顾四周

String[] elements = str.split("(?<=[a-zà-ú]) (?=[A-ZÀ-Ú])");
  • (?<=[a-zà-ú]) 看后面的断言。检查 space 前面是否有 class 中的字符。但是这个不会消耗字符

  • (?=[A-ZÀ-Ú]) 向前看断言。检查 space 是否后跟任何这些字符。

Regex Demo

测试

String str = "Filtración con membrana - Nanofiltración Ósmosis inversa Desinfección";
String[] elements = str.split("(?<=[a-zà-ú]) (?=[A-ZÀ-Ú])");
for (String i : elements)
    System.out.println(i);

将输出为

Filtración con membrana - Nanofiltración
Ósmosis inversa
Desinfección

您可以使用:

String str = "Filtración con membrana - Nanofiltración Ósmosis inversa Desinfección";
String[] toks = str.split( "(?<=\p{javaLowerCase}) +(?=\p{javaUpperCase})" );
for (String tok: toks)
    System.out.printf("=> <%s>%n", tok);

输出:

=> <Filtración con membrana - Nanofiltración>
=> <Ósmosis inversa>
=> <Desinfección>

此正则表达式匹配 1 个或多个 space 并使用前瞻模式 (?=\p{javaUpperCase}),这意味着 space 后必须跟一个 unicode 大写字母。它还使用后向 (?<=\p{javaLowerCase}),这意味着 space 前面必须有一个 unicode 小写字母。