【问题标题】:Java RegEx :What's the difference between .* and \s\S?Java RegEx:.* 和 \s\S 有什么区别?
【发布时间】:2019-05-05 16:50:44
【问题描述】:

我看书或上网,结果说.\n通常等于\s\S\d\D\w\W,表示所有字符。但现在我想得到消息从某个字符串中,我发现我只能使用.\n。我的代码有什么问题?为什么我不能使用\s\S 表达式?

String srcMsg="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root><resultCode>00000</resultCode><resultDesc><![CDATA[00000:<ResponseClass Name=\"Response\">\n    <ResponseSubClass Name=\"attributesResponse\">\n         <ITEM>0</ITEM>\n </ResponseSubClass>\n</ResponseClass>]]></resultDesc></root>";
//The right code 
java.util.regex.Pattern pP0 = java.util.regex.Pattern.compile(".*<!\\[CDATA\\[00000:((.|\n)*)\\]\\]>.*"); 
//wrong code1 
//java.util.regex.Pattern pP0 = java.util.regex.Pattern.compile(".*<!\\[CDATA\\[00000:(\\s|\\S)*\\]\\]>.*");
//wrong code2 
//java.util.regex.Pattern pP0 = java.util.regex.Pattern.compile(".*<!\\[CDATA\\[00000:[\\w|\\W]*\\]\\]>.*");
java.util.regex.Matcher mP0= pP0.matcher(srcMsg);
if(mP0.find())
para=mP0.group(1);
int dsi3 = para.indexOf("<ITEM>") + "<ITEM>".length();
int dsi4 = para.indexOf("</ITEM>");
System.out.println(Integer.valueOf(para.substring(dsi3, dsi4)));

【问题讨论】:

  • . dot 匹配除换行符之外的所有内容。 [\S\s] 是一个包含所有事物和所有事物的类,结果是它匹配所有字符。
  • 你之前已经被指出过...你为什么忽略它? stackoverflow.com/questions/1732348/…
  • 您真的不想尝试使用正则表达式对 X(HT)ML 进行一般解析。这就像试图使用钝头螺丝刀雕刻复杂的硬木卷轴一样。结果永远不会被接受,必须收拾烂摊子的开发人员将永远诅咒你的名字。帮自己一个忙,使用真正的解析器。

标签: java regex regex-group


【解决方案1】:

默认情况下,. 模式不匹配行终止符,即 \R 匹配的内容:

任何 Unicode 换行序列,都等价于\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

一个[] 字符类结合了两个对手预定义的字符类将匹配所有字符,例如[\d\D][\h\H][\s\S][\v\V][\w\W][\p{L}\P{L}]

. 模式可以通过以下方式之一设置DOTALL 标志来匹配所有字符:

// Set flag external from pattern
Pattern.compile(".", Pattern.DOTALL)

// Set flag in the pattern
Pattern.compile("(?s).")

// Set flag in part of pattern
Pattern.compile("(?s:.)")

为方便起见,这里是 DOTALL 标志的 javadoc:

启用 dotall 模式。

在 dotall 模式下,表达式. 匹配任何字符,包括行终止符。默认情况下,此表达式不匹配行终止符。

Dotall 模式也可以通过嵌入式标志表达式(?s) 启用。 (s 是“单行”模式的助记符,在 Perl 中就是这样称呼的。)

【讨论】:

    【解决方案2】:

    . dot 匹配除换行符之外的所有内容。 [\S\s] 是一个具有
    所有一件事和所有不是这件事的事情,
    结果是匹配所有字符

    正则表达式下面的代码引用了第 1 组。
    我相信您在其他 2 个正则表达式中需要一个等效的组 1。他们在这里:

    1) https://regex101.com/r/Tp1k9m/1

     .* <!\[CDATA\[00000:
     (                             # (1 start)
          (?: . | \n )*            #    Should be *?
     )                             # (1 end)
     \]\]> .* 
    

    2)https://regex101.com/r/FdoHGl/1

     .* <!\[CDATA\[00000:
     (                             # (1 start)
          (?: \s | \S )*           #    Should be *?
     )                             # (1 end)
     \]\]> .* 
    

    3)https://regex101.com/r/t3vVcB/1

     .* <!\[CDATA\[00000:
     (                             # (1 start)
          [\w\W]*                  #    Was [\w|\W], fixed it.
                                   #    Should be *?
     )                             # (1 end)
     \]\]> .* 
    

    请注意,在字符类中,有一个隐式 OR
    项之间。因此,您不必包含 or 符号
    除非你想匹配文字 |


    另外,请注意在这些正则表达式中使用贪婪运算符。
    它将立即转到字符串的末尾并回溯
    直到找到一个匹配项,该匹配项超过了所有的闭包。
    (在这种情况下\]\]&gt;

    【讨论】:

      猜你喜欢
      • 2010-12-14
      • 2021-02-26
      • 1970-01-01
      相关资源
      最近更新 更多