我有一个包含几行类似于:
的文件Name: Peter
Address: St. Serrano número 12, España
Country: Spain
我需要使用正则表达式提取地址,考虑到它可以包含点,特殊字符(ñ,ç),áéíó... ...
目前的代码有效,但看起来很丑:。
Pattern p = Pattern.compile("^(.+?)Address: ([a-zA-Z0-9ñÑçÇáéíóú., ]+)(.+?)$",
Pattern.MULTILINE | Pattern.DOTALL);
Matcher m = p.matcher(content);
if (m.matches()) { ... }
编辑:地址字段也可以分为多行
Name: Peter
Address: St. Serrano número 12,
Madrid
España
Country: Spain
编辑:我不能使用Properties对象或YAML解析器,因为该文件也包含其他类型的信息。
答案 0 :(得分:6)
我不太了解Java的正则表达式对象,但是像这种模式的东西会这样做:
^Address:\s*((?:(?!^\w+:).)+)$
假设打开了多行和dotall模式。
这将匹配以地址开头的任何行,后跟任何内容,直到换行符和单个单词后跟冒号。
如果你知道下一个字段必须是“国家”,你可以稍微简化一下:
^Address:\s*((?:(?!^Country:).)+)$
诀窍在于重复组中的先行断言。 '(?!国家:)。'将匹配除字符串'Country:'的开头之外的所有内容,因此我们只将其粘贴在非捕获括号中(?:...)并用+量化它,然后将所有这些组合在正常捕获括号中。
答案 1 :(得分:3)
您可能希望查看Properties
类而不是正则表达式。它为您提供了管理纯文本或XML文件以表示键值对的方法。
因此,您可以在示例文件中读取,然后在加载到Properties
对象后获取这样的值:
Properties properties = new Properties();
properties.load(/* InputStream of your file */);
Assert.assertEquals("Peter", properties.getProperty("Name"));
Assert.assertEquals("St. Serrano número 12, España", properties.getProperty("Address"));
Assert.assertEquals("Spain", properties.getProperty("Country"));
答案 2 :(得分:3)
假设“content”是包含文件内容的字符串,那么您的主要问题是您使用的matches()
应该使用find()
。
Pattern p = Pattern.compile("^Address:\\s*(.*)$", Pattern.MULTILINE);
Matcher m = p.matcher(content);
if ( m.find() )
{
...
}
关于MULTLINE和DOTALL模式的其他答案似乎有些混乱。 MULTILINE使^
和$
锚点分别匹配逻辑行的开头和结尾。 DOTALL让点(句点,句号,等等)匹配行分隔符,如\n
(换行)和\r
(回车)。此正则表达式必须使用MULTILINE模式,不得使用DOTALL模式。
答案 3 :(得分:1)
我不是故意成为泥巴,但你必须使用正则表达式吗?为什么不让你未来的自己(或其他人)头疼并做到:
String line = reader.readLine();
while(line != null)
{
line = line.trim();
if(line.startsWith("Address: "))
{
return line.substr("Address: ".length()).trim();
}
line = reader.readLine();
}
return null;
当然,这也可以参数化并放入方法中。
否则,我会推荐属性或JYaml建议。
答案 4 :(得分:0)
不是Java人员,但"Address: (.*)$"
不会工作吗?
编辑:没有Pattern.MULTILINE | Pattern.DOTALL选项应仅匹配该行。
答案 5 :(得分:0)
它可以包含换行符吗?如果它不能包含换行符,则不需要使用多行修饰符,而是可以使用
Pattern p = Pattern.compile("^Address: (.*)$");
如果可以的话,我能想到的另一种选择是
Pattern p = Pattern.compile("Address: (.*)\nCountry", Pattern.MULTILINE);
如果没有DOTALL,点将与换行符不匹配,因此您可以在正则表达式中明确指定它,从而可以执行您所询问的内容。
答案 6 :(得分:0)