Java 正则表达式:.* 和 \s\S 有什么区别?
Java RegEx :What's the difference between .* and \s\S?
看书或者上网查,结果说.\n
通常等于\s\S
或\d\D
或\w\W
,意思是全部character.But 现在我想从某个字符串中获取消息,我发现我只能使用 .\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)));
默认情况下,.
模式不匹配行终止符,即 \R
匹配:
Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
一个 []
字符 class 结合了两个对手预定义字符 classes 将匹配所有字符,例如[\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:
Enables dotall mode.
In dotall mode, the expression .
matches any character, including a line terminator. By default this expression does not match line terminators.
Dotall mode can also be enabled via the embedded flag expression (?s)
. (The s
is a mnemonic for "single-line" mode, which is what this is called in Perl.)
.
点匹配除换行符以外的所有内容。 [\S\s]
是一个 class 有
所有的一件事和所有不是那件事的东西,
结果是匹配所有字符
正则表达式下方的代码引用组 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)
\]\]> .*
注意在字符classes中,有一个隐含的OR
项之间。因此,您不必包含或符号
在那里,除非你想匹配文字 |
此外,请注意在这些正则表达式中使用贪心运算符。
它会立即转到字符串的末尾并回溯
直到它找到一个匹配项,它超过了所有的闭包。
(在这种情况下 \]\]>
)
看书或者上网查,结果说.\n
通常等于\s\S
或\d\D
或\w\W
,意思是全部character.But 现在我想从某个字符串中获取消息,我发现我只能使用 .\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)));
默认情况下,.
模式不匹配行终止符,即 \R
匹配:
Any Unicode linebreak sequence, is equivalent to
\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
一个 []
字符 class 结合了两个对手预定义字符 classes 将匹配所有字符,例如[\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:
Enables dotall mode.
In dotall mode, the expression
.
matches any character, including a line terminator. By default this expression does not match line terminators.Dotall mode can also be enabled via the embedded flag expression
(?s)
. (Thes
is a mnemonic for "single-line" mode, which is what this is called in Perl.)
.
点匹配除换行符以外的所有内容。 [\S\s]
是一个 class 有
所有的一件事和所有不是那件事的东西,
结果是匹配所有字符
正则表达式下方的代码引用组 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)
\]\]> .*
注意在字符classes中,有一个隐含的OR
项之间。因此,您不必包含或符号
在那里,除非你想匹配文字 |
此外,请注意在这些正则表达式中使用贪心运算符。
它会立即转到字符串的末尾并回溯
直到它找到一个匹配项,它超过了所有的闭包。
(在这种情况下 \]\]>
)