我知道$
用于检查 Java 正则表达式中的行尾是否跟随。
以下代码:
String test_domain = "http://www.google.com/path\nline2\nline3";
test_domain = test_domain.replaceFirst("(\\.[^:/]+).*$?", "$1");
System.out.println(test_domain);
输出结果为:
http://www.google.com
line2
line3
我假设模式(\\.[^:/]+).*$?
与第一行匹配,即http://www.google.com/path
,$1
为http://www.google.com
。 ?
会产生不情愿的匹配(因此匹配第一行。)
但是,如果我删除模式中的?
并实现以下代码:
String test_domain = "http://www.google.com/path\nline2\nline3";
test_domain = test_domain.replaceFirst("(\\.[^:/]+).*$", "$1");
System.out.println(test_domain);
输出结果为:
http://www.google.com/path
line2
line3
我认为它应该给出结果http://www.google.com
(\\.[^:/]+)
匹配http://www.google.com
.*$
匹配/path\nline2\nline3
我在这里对正则表达式的误解在哪里?
答案 0 :(得分:1)
你的正则表达式与输入字符串不匹配。事实上,$
完全匹配字符串的结尾(在line3
的末尾)。由于您没有使用s
标记,.
无法到达。
此外,行/字符串锚点的$
末尾后面不能有?
量词。它对正则表达式引擎毫无意义,在Java中被忽略。
要使其正常工作,如果您只想返回s
,则需要使用http://www.google.com
标记:
String test_domain = "http://www.google.com/path\nline2\nline3";
test_domain = test_domain.replaceFirst("(?s)(\\.[^:/]+).*$", "$1");
System.out.println(test_domain);
this demo的输出:
http://www.google.com
使用多行(?m)
标记,正则表达式将处理每一行,查找文字.
,然后处理:
和/
以外的字符序列。当找到其中一个字符时,该行上的其余字符将被省略。
String test_domain = "http://www.google.com/path\nline2\nline3";
test_domain = test_domain.replaceFirst("(?m)(\\.[^:/]+).*$", "$1");
System.out.println(test_domain);
this IDEONE demo的输出:
http://www.google.com
line2
line3
答案 1 :(得分:1)
您有一个多行输入并尝试在每个行的正则表达式中使用锚点$
但不使用MULTILINE
标志。您在正则表达式前面所需的只是(?m)
模式:
String test_domain = "http://www.google.com/path\nline2\nline3";
test_domain = test_domain.replaceFirst("(?m)(\\.[^:/]+).*$", "$1");
System.out.println(test_domain);
这将输出:
http://www.google.com
line2
line3
如果没有MULTILINE
或DOTALL
模式,您的正则表达式(\.[^:/]+).*$
将因.*$
的存在而无法匹配输入,因为点与新行和{{1}不匹配}(行尾)在2个换行符后出现。