我有一个包含以下内容的文本文件:
# This is a comment, do not parse this: U20:%x[-2,1]
U01:%x[-2,1]
U02:%x[-2,1]/%x[-1,1]/%x[0,1]
要求是我需要提取每行中每个方括号内的值对。
例如。对于第一行我期望获得对-2和1。 对于第二行,我期待3对值。
该行应以“U”开头,后跟至少1位数字,后跟冒号“:”。
如果该行为空或以“#”开头,则应忽略该行。
这是我使用的正则表达式,但它并没有忽略以“#”开头的行。
(?:U\d+:|/)\%x\[(?:(-?\d+),(\d+))\]
如何更改正则表达式以使其正常工作?
答案 0 :(得分:12)
您可以将此模式与全球研究结合使用:
(?m:^U\d+:|\G/)%x\[(-?\d+),(-?\d+)\]
模式细节:
(?m: # non capturing group with the multiline modifier
^ # anchor: start of the line
U\d+: # literal "U" followed by digits and :
| # OR
\G/ # literal "/" contiguous to a precedent match
)
%x\[(-?\d+),(-?\d+)\]
示例:
Pattern p = Pattern.compile("(?m:^U\\d+:|\\G/)%x\\[(-?\\d+),(-?\\d+)\\]");
Matcher m = p.matcher(s); // s is all the content of your txt file
while (m.find()) {
System.out.print(m.group(1) + "," + m.group(2));
}
如果允许两个%x[a,b]
之间的其他内容,您可以将模式更改为:
(?m:^U\d+:|\G(?>[^#\n/]++|/(?!%x\[))*/)%x\[(-?\d+),(-?\d+)\]
或
(?m:^U\d+:|\G[^#\n]*?/)%x\[(-?\d+),(-?\d+)\]
请注意,添加的子模式与评论不匹配,因为字符#
从字符类中排除
另一种方式:由于您的数据位于文本文件中,您可以逐行读取文件并使用其中一种先前模式提取数字(在这种情况下,您可以删除m修饰符)。优点是你知道数字来自哪一行。
答案 1 :(得分:3)
您可以使用REGEX (?:[^\\[]*)(?:\\[)(-?\\d+),(\\d+)(?=\\])
查找[
和]
之间的匹配。
说明:
<强> CODE:强>
String ar[] ={ "# This is a comment, do not parse this: U20:%x[-2,1]",
"U01:%x[-2,1]",
"U02:%x[-2,1]/%x[-1,1]/%x[0,1]"};
String REGEX = "(?:[^\\[]*)(?:\\[)(-?\\d+),(\\d+)(?=\\])";
Pattern p = Pattern.compile(REGEX);
for(String theString:ar){
if(!theString.matches("^U\\d+:.*"))
continue;
Matcher m = p.matcher(theString);
while (m.find()) {
String matched = m.group(1);
String matched1 = m.group(2);
System.out.println("Mached : "+ matched +", "+ matched1);
}
}
<强>输出:强>
Mached : -2, 1
Mached : -2, 1
Mached : -1, 1
Mached : 0, 1
答案 2 :(得分:0)
如果您正在使用具有正则表达式功能的文本编辑器(有负载,我喜欢notepad ++),那么您可以通过首先删除注释来完成此操作。我认为这是最简单的方法。执行以下替换正则表达式:
^(?: |\t)*#.*?$
并使用空字符串作为替换。然后,您没有将注释与原始表达式匹配的危险(假设注释字符哈希总是出现在行的开头)。
(?:U\d+:|/)\%x\[(?:(-?\d+),(\d+))\]
答案 3 :(得分:0)
我不参与java,但这个似乎是这样做的:
(?:^#.*?$|^U\d+|%x\[(-?\d+),(-?\d+)\])
使用全局多线模式。
Expl。:(非捕获)匹配 -
如果选项3是匹配项,请抓取实际值。 由于替代执行顺序所有注释行都将被“删除”。
也许你需要一些采用它才能在java中工作。
问候。
答案 4 :(得分:0)
我认为这项工作:
([^#]?:U\d+:|/)\%x\[(?:(-?\d+),(\d+))\]
我们在开头后添加[^#](表示不以#
开头)答案 5 :(得分:0)
我的朋友这对你有用
public static void main(String []args){
BufferedReader bufferReader = null;
String line="";
try {
bufferReader = new BufferedReader(new FileReader("<file_path>"));
Pattern p = Pattern.compile("(?m:^U\\d+:|\\G/)%x\\[(-?\\d+),(-?\\d+)\\]");
while ((line = bufferReader.readLine()) != null) {
Matcher m = p.matcher(line);
while (m.find()) {
System.out.println(m.group(1) + "," + m.group(2));
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
try {
bufferReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
}
答案 6 :(得分:0)
老兄这里是一个简单的RegEx:
\[-*\d+,-*\d+\]
就是这样!!!
答案 7 :(得分:0)
更简单的技巧将在多线模式下完成工作:
(?m)(?:(?:#.*$)|%x\[(-?\d+),(\d+)\])
答案 8 :(得分:0)
我建议分几步解决问题 1st:遍历所有行,跳过注释(由#开头的行) 第二:对于不是注释的每一行,在括号之间提取字符串
//得到答案 ArrayList valuePairs = new ArrayList();
//逐行读取文件 bufferReader = new BufferedReader(new FileReader(“”));
while((line = bufferReader.readLine())!= null) { //跳过评论 if(line.charAt(0)=='#')继续;
// finds value pairs (start and ends with a bracket, brackets not included)
Pattern p = Pattern.compile("(?<=\[)[^\]]*(?=\])");
Matcher m = p.matcher(line);
while (m.find())
{
valuePairs.add(m.group(0));
}
}
这段代码是在IDE之外编写的,我假设缺少一些try / catch但是这个想法就在那里。
答案 9 :(得分:-2)
如果你的正则表达式几乎适合你,你只需要在它前面添加一行“^”:
^(?:U\d+:|/)\%x\[(?:(-?\d+),(\d+))\]