为什么正则表达式不匹配

时间:2016-06-20 11:50:56

标签: java regex

我写了以下代码:

public static void main(String[] args) {


        // String to be scanned to find the pattern.
        String line = "'7858','1194','FSP,FRB,FWF,FBVS,FRRC','15'\n"
                + "'7859','1194','FIRM','21'";
        String pattern = "^'*','*','*','*'$";

        // Create a Pattern object
        Pattern r = Pattern.compile(pattern);

        // Now create matcher object.
        Matcher m = r.matcher(line);
        if (m.find()) {
            System.out.println("Found value: " + m.group(0));
            System.out.println("Found value: " + m.group(1));               
        } else {
            System.out.println("NO MATCH");
        }

    }

它总是返回NO MATCH

预期结果 - 2行

我错了什么?

3 个答案:

答案 0 :(得分:3)

您的代码中存在几个问题:

  • 单个“星”(*)匹配其后跟的字符的0-N倍 - 在您的代码中,'*'表示“匹配单引号的0-N次,后跟另一个单引号”
  • 此外,“star”限定符默认为“贪婪”,这意味着它将尽可能多地使用匹配字符,包括组中的结尾引号。在您的情况下,您可能希望将其设置为“不情愿”模式(通过向其添加?*?),以便它仅匹配单引号内的文本。
  • 必须逐行匹配行,因此必须在行分隔符(\n)上拆分初始多行。除非你使用多行匹配选项,但我认为这不是你想要的。
  • 匹配组从1开始,而不是0,因此在您的情况下,组将编号为1到4。

以下是您的代码,如上所述进行了更正:

public static void main(String[] args) {

    String line = "'7858','1194','FSP,FRB,FWF,FBVS,FRRC','15'\n" +
            "'7859','1194','FIRM','21'";

    Pattern r = Pattern.compile("'(.*?)','(.*?)','(.*?)','(.*?)'");

    String[] lines = line.split("\n");
    for (String l : lines) {

        System.out.println("Line : " + l);

        Matcher m = r.matcher(l);
        if (m.find()) {
            System.out.println("Found value: " + m.group(1));
            System.out.println("Found value: " + m.group(2));
            System.out.println("Found value: " + m.group(3));
            System.out.println("Found value: " + m.group(4));
        } else {
            System.out.println("NO MATCH");
        }
    }

}

结果如下:

Line : '7858','1194','FSP,FRB,FWF,FBVS,FRRC','15'
Found value: 7858
Found value: 1194
Found value: FSP,FRB,FWF,FBVS,FRRC
Found value: 15
Line : '7859','1194','FIRM','21'
Found value: 7859
Found value: 1194
Found value: FIRM
Found value: 21

答案 1 :(得分:0)

"^'*','*','*','*'$"与任何内容都不匹配,因为'*会尽可能多地搜索'。它与你想要的不符。 此外,^和$赢了。

我认为这个正则表达式是你需要的:

'[0-9A-Z,]*','[0-9A-Z,]*','[0-9A-Z,]*','[0-9A-Z,]*'

在这里,我添加了字符类[0-9A-Z,]以匹配数字,字母和, s。我认为这会给你你所需要的。

答案 2 :(得分:0)

您可以尝试使用此表达式:

(?<=^|[\r\n]+)'([^']*)','([^']*)','([^']*)','([^']*)'(?=[\r\n]+|$)

故障:

  • (?<=^|[\r\n]+)是对输入开头或一系列换行符进行正面的后视检查

  • '([^']*)'匹配并捕获您的某个群组。您可以使用'(.*?)'(即不情愿的限定符),但前一版本更安全,因为如果您的输入行包含4个以上的组,它将不匹配

  • (?=[\r\n]+|$)是一个积极的预测,检查您的组后面是输入序列末尾的一系列换行符字符

我还对您的代码做了以下假设:

  • 您的输入包含多行,您不能或不想分割(否则String[] lines = input.split("[\\r\\n]+")会更好)。
  • 匹配行始终由您要使用group(1)等访问的4个组组成。
  • 您的论坛可以包含除单引号外的任何字符。如果一个群组只允许包含某些字符(例如数字),那么在表达式中反映这一点会更安全(例如'[0-9]+'