【问题标题】:Java split is eating my charactersJava 分裂正在吞噬我的角色
【发布时间】:2011-02-18 16:21:06
【问题描述】:

我有一个这样的字符串String str = "la$le\\$li$lo"

我想拆分它以获得以下输出"la","le\\$li","lo"。 \$ 是 $ 转义的,所以它应该留在输出中。

但是当我执行str.split("[^\\\\]\\$") 时,你会得到"l","le\\$l","lo"

从我得到的正则表达式匹配 a$ 和 i$ 然后删除。知道如何让我的角色回来吗?

谢谢

【问题讨论】:

  • String str = "la$le\$li$lo"?你的意思是String str = "la$le\\$li$lo" ??
  • 转义符也可以转义吗?如果是这样,正则表达式就不行了(regex-es 不能算!)。

标签: java regex string split


【解决方案1】:

使用零宽度匹配断言:

    String str = "la$le\\$li$lo";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<!\\\\)\\$")
    )); // prints "[la, le\$li, lo]"

正则表达式本质上是

(?<!\\)\$

它使用否定的lookbehind来断言前面没有\

另见


更多关于断言的拆分示例

简单的分句,保留标点符号:

    String str = "Really?Wow!This.Is.Awesome!";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=[.!?])")
    )); // prints "[Really?, Wow!, This., Is., Awesome!]"

使用\G将长字符串分成固定长度的部分

    String str = "012345678901234567890";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=\\G.{4})")
    )); // prints "[0123, 4567, 8901, 2345, 6789, 0]"

使用后向/前瞻组合:

    String str = "HelloThereHowAreYou";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=[a-z])(?=[A-Z])")
    )); // prints "[Hello, There, How, Are, You]"

相关问题

【讨论】:

  • @Fenris:不同之处在于,如果$ 是第一个字符,我的正则表达式仍然可以拆分它,而您的则不能,因为它坚持在它前面有一个字符(即不是斜线)。
【解决方案2】:

a$ 和 i$ 被删除的原因是正则表达式 [^\\]\$ 匹配任何不是“\”后跟“$”的字符。你需要使用zero width assertions

这与人们试图找到 q 后面没有 u 的问题相同。

正确的正则表达式的第一个剪切是/(?&lt;!\\)\$/(Java 中的"(?&lt;!\\\\)\\$"

class Test {
 public static void main(String[] args) {
  String regexp = "(?<!\\\\)\\$";
  System.out.println( java.util.Arrays.toString( "1a$1e\\$li$lo".split(regexp) ) );
 }
}

产量:
[1a, 1e\$li, lo]

【讨论】:

    【解决方案3】:

    您可以尝试先将“\$”替换为另一个字符串,例如$的URL编码(“%24”),然后拆分:

    String splits[] = str.replace("\$","%24").split("[^\\\\]\\$");
    for(String str : splits){
       str = str.replace("%24","\$");
    }
    

    更一般地说,如果 str 是由类似的东西构造的

    str = a + "$" + b + "$" + c
    

    然后您可以在将 a、b 和 c 附加在一起之前对它们进行 URLEncode

    import java.net.URLEncoder.encode;
    ...
    str = encode(a) + "$" + encode(b) + "$" + encode(c)
    

    【讨论】:

    • 好点。我更新了我的回复以获得更通用的解决方案,假设您正在拆分 str 因为它实际上由您首先附加在一起的三个字符串组成。
    【解决方案4】:
    import java.util.regex.*;
    public class Test {
        public static void main(String... args) {
            String str = "la$le\\$li$lo";
            Pattern p = Pattern.compile("(.+?)([^\\\\]\\$)");
            Matcher m = p.matcher(str);
            while (m.find()) {
                System.out.println(m.group(1));
                System.out.println(m.group(2));
            }
        }
    }
    

    给予

    l
    a$
    le\$l
    i$
    

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      相关资源
      最近更新 更多