将正则表达式模式重构为Java风味模式

时间:2019-05-23 09:33:49

标签: java regex refactoring

我在regex101.com上创建了一个正则表达式模式: https://regex101.com/r/cMvHlm/7/codegen?language=java

但是,该正则表达式似乎无法在我的Java程序中运行(我使用spring toolsuite作为IDE):

@Test
    public void testRegex() {
        //Pattern referenceCodePattern = Pattern.compile("((\\h|\\:)+)(([\u00DFA-Za-z0-9-_#\\\\\\/])+)(([[:punct:]])?)");
        Pattern pattern = Pattern.compile(""
                + "(?:\\s+|chiffre|job-id|job-nr[.]|job-nr|\\bjob id\\b|job nr[.]|jobnummer|jobnr[.]|jobid|jobcode|job nr.|ziffer|kennziffer|kennz.|referenz code|referenz-code|"
                + "referenzcode|ref[.] nr[.]|ref[.] id|ref id|ref[.]id|ref[.]-nr[.]|ref[.]- nr[.]|"
                + "referenz nummer|referenznummer|referenz nr[.]|stellenreferenz| referenz-nr[.]|referenznr[.]|referenz|referenznummer der stelle|id#|id #|stellenausschreibungen|" 
                + "stellenausschreibungs\\s?nr[.]|stellenausschreibungs-nr[.]|stellenausschreibungsnr[.]|stellenangebots id|stellenangebots-id|stellenangebotsid|stellen id|stellen-id|stellenid|stellenreferenz|"
                + "stellen-referenz|ref[.]st[.]nr[.]|stellennumer|\\bst[.]-nr[.]\\b|\\bst[.] nr[.]\\b|kenn-nr[.]|positionsnummer|kennwort|stellenkey|stellencode|job-referenzcode|stellenausschreibung|"
                + "bewerbungskennziffer|projekt id|projekt-id|reference number|reference no[.]|reference code|job code|job id|job vacancy no[.]|job-ad-number|auto req id|job ref|\\bstellenausschreibung nr[.]\\b)"
                + ":?(?:\\w*)(?:\\s*)([A-Z]*\\s*)([!\"#$%&'()*+,\\-.\\/:;<=>?@[\\]^_`{|}~]*\\w*[!\"#$%&'()*+,\\-.\\/:;<=>?@[\\]^_`{|}~]*\\w*[!\"#$%&'()*+,\\-.\\/:;<=>?@[\\]^_`{|}~]*\\w*[!\"#$%&'()*+,\\-.\\/:;<=>?@[\\]^_`{|}~]*)?");

        String line = "Referenznummer: INDUSTRY Kontakt: ZAsdfsdfS Herr Andrafgdh Neue Str. 7 21244 Buchholz +42341 22322 mdjob.bu44lz@zaqusssis.de Stellenanzeige teilen: Jetzt online bewerben! oder bewerben Sie sich mit\n" +
            "Geben Sie bei Ihrer Bewerbung die Stellenreferenz und die Stellenbezeichnung an! \n" +
            "Stellenreferenz:   21533448-JOtest\n\n" +
            "Stellenausschreibung Nr. PD-666/19";


          // Create a Pattern object
          //Pattern r = Pattern.compile(pattern);
          Matcher m = pattern.matcher(line);
          if (m.find( )) {
             System.out.println("Found value: " + m.group(0) );
             System.out.println("Found value: " + m.group(1) );
             System.out.println("Found value: " + m.group(2) );
          }else {
             System.out.println("NO MATCH");
          }                 
    }

我收到以下错误:

    java.util.regex.PatternSyntaxException: Unclosed character class near index 1337

    at java.util.regex.Pattern.error(Pattern.java:1957)
    at java.util.regex.Pattern.clazz(Pattern.java:2550)
    at java.util.regex.Pattern.clazz(Pattern.java:2506)
    at java.util.regex.Pattern.clazz(Pattern.java:2506)
    at java.util.regex.Pattern.clazz(Pattern.java:2506)
    at java.util.regex.Pattern.sequence(Pattern.java:2065)
    at java.util.regex.Pattern.expr(Pattern.java:1998)
    at java.util.regex.Pattern.group0(Pattern.java:2907)
    at java.util.regex.Pattern.sequence(Pattern.java:2053)
    at java.util.regex.Pattern.expr(Pattern.java:1998)
    at java.util.regex.Pattern.compile(Pattern.java:1698)
    at java.util.regex.Pattern.<init>(Pattern.java:1351)
    at java.util.regex.Pattern.compile(Pattern.java:1028)

有没有办法找出索引1337在哪里?

2 个答案:

答案 0 :(得分:1)

正则表达式的主要问题是[]都必须在Java正则表达式的字符类中转义,因为它们用于形成字符类的并集和交集,是“特殊的”那里。

另一个问题是[.]\b模式无法按预期工作,因为非单词char后面的单词边界将要求单词char立即位于当前位置的右边。您在那里需要\B,而不是\b

您需要以Java regex模式对/字符进行转义。

您不必在正则表达式的末尾重复该模式,可以用一个非捕获组{0,3}将重复的模式包装起来后,用一个有限的(?:...)量词来“重复”该模式。

考虑一个while块以获取所有匹配项。您可以使用布尔值标志来查看是否存在任何匹配项。

另外,您可能想使用\\s+作为第一组中的最后一个,它太通用了,但我暂时将其保留在开头。

使用

Pattern pattern = Pattern.compile(""
                + "(?:\\s+|chiffre|job-id|job-nr[.]|job-nr|\\bjob id\\b|job nr[.]|jobnummer|jobnr[.]|jobid|jobcode|job nr\\.|ziffer|kennziffer|kennz\\.|referenz code|referenz-code|"
                + "referenzcode|ref[.] nr[.]|ref[.] id|ref id|ref[.]id|ref[.]-nr[.]|ref[.]- nr[.]|"
                + "referenz nummer|referenznummer|referenz nr[.]|stellenreferenz| referenz-nr[.]|referenznr[.]|referenz|referenznummer der stelle|id#|id #|stellenausschreibungen|" 
                + "stellenausschreibungs\\s?nr[.]|stellenausschreibungs-nr[.]|stellenausschreibungsnr[.]|stellenangebots id|stellenangebots-id|stellenangebotsid|stellen id|stellen-id|stellenid|stellenreferenz|"
                + "stellen-referenz|ref[.]st[.]nr[.]|stellennumer|\\bst[.]-nr[.]\\B|\\bst[.] nr[.]\\B|kenn-nr[.]|positionsnummer|kennwort|stellenkey|stellencode|job-referenzcode|stellenausschreibung|"
                + "bewerbungskennziffer|projekt id|projekt-id|reference number|reference no[.]|reference code|job code|job id|job vacancy no[.]|job-ad-number|auto req id|job ref|\\bstellenausschreibung nr[.]\\B)"
                + ":?\\w*\\s*([A-Z]*\\s*)([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]^_`{|}~]*(?:\\w*[!\"#$%&'()*+,\\-./:;<=>?@\\[\\]^_`{|}~]*){0,3})?");

String line = "Referenznummer: INDUSTRY Kontakt: ZAsdfsdfS Herr Andrafgdh Neue Str. 7 21244 Buchholz +42341 22322 mdjob.bu44lz@zaqusssis.de Stellenanzeige teilen: Jetzt online bewerben! oder bewerben Sie sich mit\n" +
            "Geben Sie bei Ihrer Bewerbung die Stellenreferenz und die Stellenbezeichnung an! \n" +
            "Stellenreferenz:   21533448-JOtest\n\n" +
            "Stellenausschreibung Nr. PD-666/19";


Matcher m = pattern.matcher(line);
boolean found = false;
while (m.find()) {
     found = true;
     System.out.println("Found value: " + m.group(0) );
     System.out.println("Found value: " + m.group(1) );
     System.out.println("Found value: " + m.group(2) );
     System.out.println(" ----------------------- " );
}
if (!found) {
     System.out.println("NO MATCH");
}                 

请参见this Java demo

答案 1 :(得分:0)

在 Java 中,未转义的 [ 始终被视为开放类语法,而不是文字。 这就是为什么有些人建议总是转义文字类元字符 [] 它可以翻译大多数引擎。

转换

    [!"#$%&'()*+,\-.\/:;<=>?@[\]^_`{|}~] 
to  [!-/:-@\[\]-`{-~]  

然后重构正则表达式。
(请注意,正则表达式也可能存在可用性问题。)

重构前:

(?:\s+|chiffre|job-id|job-nr[.]|job-nr|\bjob[ ]id\b|job[ ]nr[.]|jobnummer|jobnr[.]|jobid|jobcode|job[ ]nr.|ziffer|kennziffer|kennz.|referenz[ ]code|referenz-code|referenzcode|ref[.][ ]nr[.]|ref[.][ ]id|ref[ ]id|ref[.]id|ref[.]-nr[.]|ref[.]-[ ]nr[.]|referenz[ ]nummer|referenznummer|referenz[ ]nr[.]|stellenreferenz|[ ]referenz-nr[.]|referenznr[.]|referenz|referenznummer[ ]der[ ]stelle|id\#|id[ ]\#|stellenausschreibungen|stellenausschreibungs\s?nr[.]|stellenausschreibungs-nr[.]|stellenausschreibungsnr[.]|stellenangebots[ ]id|stellenangebots-id|stellenangebotsid|stellen[ ]id|stellen-id|stellenid|stellenreferenz|stellen-referenz|ref[.]st[.]nr[.]|stellennumer|\bst[.]-nr[.]\b|\bst[.][ ]nr[.]\b|kenn-nr[.]|positionsnummer|kennwort|stellenkey|stellencode|job-referenzcode|stellenausschreibung|bewerbungskennziffer|projekt[ ]id|projekt-id|reference[ ]number|reference[ ]no[.]|reference[ ]code|job[ ]code|job[ ]id|job[ ]vacancy[ ]no[.]|job-ad-number|auto[ ]req[ ]id|job[ ]ref|\bstellenausschreibung[ ]nr[.]\b):?(?:\w*)(?:\s*)([A-Z]*\s*)([!"#$%&'()*+,\-.\/:;<=>?@\[\]^_`{|}~]*(?:\w*[!"#$%&'()*+,\-.\/:;<=>?@\[\]^_`{|}~]*){3})?

重构后:

(?:\s+|chiffre|job(?:-(?:id|nr[.]?|referenzcode|ad-number)|[ ](?:(?:nr|vacancy[ ]no)[.]|code|id|ref)|n(?:ummer|r[.])|id|code)|\b(?:job[ ]id|st(?:[.][ \-]|ellenausschreibung[ ])nr[.])\b|(?:bewerbungskenn)?ziffer|kenn(?:z(?:iffer|.)|-nr[.]|wort)|ref(?:eren(?:z(?:[ ](?:code|n(?:ummer|r[.]))|-?code|n(?:ummer|r[.]|ummer[ ]der[ ]stelle))?|ce[ ](?:n(?:umber|o[.])|code))|[.](?:[ ](?:nr[.]|id)|id|(?:-[ ]?|st[.])nr[.])|[ ]id)|stellen(?:referenz|a(?:usschreibung(?:en|s(?:\s?|-)?nr[.])?|ngebots[ \-]?id)|[ ]?id|-(?:id|referenz)|numer|key|code)|[ ]referenz-nr[.]|id[ ]?\#|p(?:ositionsnummer|rojekt[ \-]id)|auto[ ]req[ ]id):?\w*\s*[A-Z]*\s*(?:[!-/:-@\[\]-`{-~]*(?:\w*[!-/:-@\[\]-`{-~]*){3})?

enter image description here