正则表达式:从不以“#”开头的字符串中提取值对

时间:2014-01-21 08:35:50

标签: java regex

我有一个包含以下内容的文本文件:

# 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+))\]

如何更改正则表达式以使其正常工作?

10 个答案:

答案 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+)(?=\\])查找[]之间的匹配。

说明:

enter image description here

enter image description here

<强> 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。:(非捕获)匹配 -

  1. 以#
  2. 开头的整行
  3. 有效行的开头(联合国)
  4. 或实际数据
  5. 如果选项3是匹配项,请抓取实际值。 由于替代执行顺序所有注释行都将被“删除”。

    也许你需要一些采用它才能在java中工作。

    Check it out here

    问候。

答案 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+))\]