【问题标题】:Anyone know why String.matches(regexp) not working on ANSI colored string?任何人都知道为什么 String.matches(regexp) 不适用于 ANSI 彩色字符串?
【发布时间】:2015-08-06 06:36:10
【问题描述】:

我试图在任何时候找到以下字符时与正则表达式匹配:|<>- in a string array that has been split("\n"); 我的代码如下:

String[] s_array = perged.split("\n");

    for (String s_array1 : s_array) {

        if (s_array1.matches("(.*)[|><-](.*)")) {

            System.out.println("~m~" + s_array1);

        } else {

           System.out.print("~false~");

           System.out.println(s_array1);
        }
    }

试图匹配的众多字符串之一是:

 <---------^--------->
 | HH#...........### |  Exits

这些应该匹配,如果我只是复制粘贴字符串,它们将使用我的正则表达式测试为真。但是,正在解析的实际字符串中包含\u001B ANSI 颜色代码字符。我相信这些是造成问题的原因。因此,我尝试了 (\\D*) 而不是 (.*),但它仍然无法正常工作,认为 '.' 可能不接受 \u001B 字符。

  if (s_array1.matches("(\\D*)[|><-](\\D*)")) {

被解析的实际字符串如下所示:

[37;1m<[0m[34;1m---------[0m[37;1m^[0m[34;1m---------[0m[37;1m>[0m[34;1m[0m\u000D\u000A
 [34;1m| [0m[0m[35mHH[0m[0m[37m#[0m[0m[33m..........[0m[1;32mp[0m[0m[37m###[0m[34;1m |[0m  Exits:  \u000D\u000A

任何帮助将不胜感激。我不承诺为此使用匹配项,我只是不想这样做

 if(s_array1.contains("<") || s_array1.contains(">") ....

如果将来存在相同类型的问题,我更喜欢更高级的方法。

编辑

我现在尝试了一个临时字符串来删除它仍在评估为false 的转义:

String[] s_array = perged.split("\n");

    for (String s_array1 : s_array) {

        String temp=s_array1.replaceAll("\u001B", "");
        System.out.println(temp);
        if (temp.matches("(.*)[|><-](.*)")) {

            System.out.println("~m~" + s_array1);

        } else {

           System.out.print("~false~");

           System.out.println(s_array1);

        }

    }

一个简单的测试评估为true,所以我不确定是否有字符或字节可以强制表达式为false

String s="[37;1m<[0m[34;1m---------[0m[37;1m^[0m[34;1m---------[0m[37;1m>[0m[34;1m[0m  Loc:    [36mDortlewall (Crystite plaza)                    [m";
    if(s.matches("(.*)[|><-](.*)")){
        System.out.println("It was true yay!!");
    }else
    System.out.println("It was false BOOO:");

【问题讨论】:

  • 文字 '\' 字符的 utf-16 表示是 \u001B。在解析器解码\u001B 之后,它会将文字转义放入现在内存中的字符串中。我不明白你的意思。如果内存中的字符串包含转义,则包含 metachar . dot 的正则表达式将匹配它。
  • 评估为假我不知道为什么。我更新了我第二次绕过字符串的尝试,但是它不会使用 String.matches() 评估为真。
  • 尝试使用 Dot-All 修饰符标志(或用[\S\s] 代替点)。可能是类中的字符在字符串中的不同行上。
  • replaceAll("\u001B") 最好以replaceAll("\\u001B")replaceAll("\\\\") 的形式传递给引擎,因为在内存中,引擎必须看到\u001B\\ ,在代码中,解析器应该看到"\\\\"
  • 您是否有机会发布具有 ANSI 控制字符的输入样本? (作为 Dropbox 上的文件或其他东西;可能无法可靠地将其作为文本合并到您的问题中。例如,最后一个使用字符串文字的测试不会包含实际的控制字符。)

标签: java regex string


【解决方案1】:

我将 if 条件更改为使用 java.util.regex.Pattern

    String perged = "[37;1m<[0m[34;1m---------[0m[37;1m^[0m[34;1m---------[0m[37;1m>[0m[34;1m[0m  Loc:    [36mDortlewall (Crystite plaza)                    [m";
    String[] s_array = perged.split("\n");

    for (String s_array1 : s_array) {

        if (Pattern.matches("(.*)[|><-](.*)" , s_array1)) {

            System.out.println("~m~" + s_array1);

        } else {

           System.out.print("~false~");

           System.out.println(s_array1);
        }
    }


}

这会打印出来

~m~[37;1m&lt;[0m[34;1m---------[0m[37;1m^[0m[34;1m---------[0m[37;1m&gt;[0m[34;1m[0m Loc: [36mDortlewall (Crystite plaza) [m

如果在Loc: 之前恰好有一个\n,结果将是:

~m~[37;1m<[0m[34;1m---------[0m[37;1m^[0m[34;1m---------[0m[37;1m>[0m[34;1m[0m
~false~Loc: [36mDortlewall (Crystite plaza)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-30
    • 2018-07-26
    • 1970-01-01
    • 2021-06-10
    • 2020-06-12
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    相关资源
    最近更新 更多