我目前正在尝试学习如何使用正则表达式,所以请关注我的简单问题。例如,假设我有一个输入文件,其中包含由换行符分隔的一堆链接:
www.foo.com/Archives/monkeys.htm
Monkey的网站描述。www.foo.com/Archives/pigs.txt
猪的网站描述。www.foo.com/Archives/kitty.txt
Kitty网站的描述。www.foo.com/Archives/apple.htm
Apple的网站描述。
如果我想获得一个网站及其描述,这个正则表达式似乎适用于测试工具:.*www.*\\s.*Pig.*
然而,当我尝试在我的代码中运行它时似乎不起作用。这个表达是否正确?我尝试用“\ n”替换“\ s”,它似乎仍无法正常工作。
答案 0 :(得分:50)
这些行可能在您的文件中以\r\n
分隔。 \r
(回车)和\n
(换行)都被认为是Java正则表达式中的行分隔符,.
元字符与它们中的任何一个都不匹配。 \s
会匹配这些字符,因此它会消耗\r
,但会使.*
与\n
匹配,但会失败。您的测试人员可能只使用\n
来分隔由\s
消耗的行。
如果我是对的,将\s
更改为\s+
或[\r\n]+
应该可以让它发挥作用。在这种情况下,这可能就是您需要做的所有事情,但有时您必须恰好匹配一个行分隔符,或者至少跟踪您匹配的数量。在这种情况下,您需要一个与三种最常见的行分隔符类型中的任何一种完全匹配的正则表达式:\r\n
(Windows / DOS),\n
(Unix / Linus / OSX)和{{1} (旧Mac)。其中任何一个都可以:
\r
更新:从Java 8开始,我们还有另一个选项\R
。它匹配任何行分隔符,不仅包括\r\n|[\r\n]
\r\n|\n|\r
,还包括Unicode standard定义的其他几个行分隔符。它等同于:
\r\n
以下是您可以使用它的方式:
\r\n|[\n\x0B\x0C\r\u0085\u2028\u2029]
(?im)^.*www.*\R.*Pig.*$
选项使其不区分大小写,i
将其置于多行模式,允许m
和^
在行边界匹配。
答案 1 :(得分:12)
为了将来参考,还可以将Pattern.DOTALL标志用于“。”。甚至匹配\ r或\ n。
示例:
假设我们正在解析一个像这样的http标题行的字符串(每行以\ r \ n结尾)
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: SAMEORIGIN
Location: http://localhost:8080/blah.htm
Content-Length: 0
这种模式:
final static Pattern PATTERN_LOCATION = Pattern.compile(".*?Location\\: (.*?)\\r.*?", Pattern.DOTALL);
可以使用“matcher.group(1)”解析位置值。
“。”在上面的模式中将匹配\ r和\ n,所以上面的模式实际上可以从http标题行解析'Location',其中可能在目标行之前或之后有其他标题(不是这是推荐的方式)解析http标头)。
此外,你可以在模式中使用“?s”来达到同样的效果。
如果你这样做,最好使用Matcher.find()。
答案 2 :(得分:1)
试试这个
([^\r]+\r[^\r])+
答案 3 :(得分:0)
适合我:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Foo {
public static void main(String args[]) {
Pattern p = Pattern.compile(".*www.*\\s.*Pig.*");
String s = "www.foo.com/Archives/monkeys.htm\n"
+ "Description of Monkey's website.\n"
+ "\n"
+ "www.foo.com/Archives/pigs.txt\n"
+ "Description of Pig's website.\n"
+ "\n"
+ "www.foo.com/Archives/kitty.txt\n"
+ "Description of Kitty's website.\n"
+ "\n"
+ "www.foo.com/Archives/apple.htm\n"
+ "Description of Apple's website.\n";
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());
} else {
System.out.println("ERR: no match");
}
}
}
问题可能与您使用Pattern和Matcher对象的方式有关吗?
答案 4 :(得分:0)
此版本匹配可能是Windows(\ r \ n)或Unix(\ n)
的换行符Pattern p = Pattern.compile("(www.*)((\r\n)|(\n))(.*Pig.*)");
String s = "www.foo.com/Archives/monkeys.htm\n"
+ "Description of Monkey's website.\n"
+ "\r\n"
+ "www.foo.com/Archives/pigs.txt\r\n"
+ "Description of Pig's website.\n"
+ "\n"
+ "www.foo.com/Archives/kitty.txt\n"
+ "Description of Kitty's website.\n"
+ "\n"
+ "www.foo.com/Archives/apple.htm\n"
+ "Description of Apple's website.\n";
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println("found: "+m.group());
System.out.println("website: "+m.group(1));
System.out.println("description: "+m.group(5));
}
System.out.println("done");
答案 5 :(得分:0)
String str="I am a "+"\n Man of Peace"+"\t"+" .";
str=str.replaceAll("[\\s|\\t|\\r\\n]+"," ").trim();
System.out.println(str);
以上示例适用于tabSpaces,newLines和常规空间。
而且我使用了java.lang.String
的trim方法来删除'str'中的所有其他空格。希望这对您和这里的其他人有帮助。