Модификация регулярных выражений PCRE Regex для C # или Java. - PullRequest
2 голосов
/ 08 мая 2019

Бизнес-требования: Адрес должен быть проанализирован по улице, номеру дома и адресной строке 2

Пример однострочных адресов

Bygholm Søpark 21B, 
Peder Skrams Gade 9  3. tv., 
Willemoesgade 29  kid.

Следующее регулярное выражение PCRE работает для вышеуказанного бизнес-сценария. Мне нужно использовать это регулярное выражение и создать метод Java, который принимает входной параметр (однострочный адрес) и возвращает вывод из групп регулярных выражений (улица, номер дома и адресная строка 2). Может ли кто-нибудь помочь мне с этим?

Regex:

/
\A\s*
(?: #########################################################################
    # Option A: [<Addition to address 1>] <House number> <Street name>      #
    # [<Addition to address 2>]                                             #
    #########################################################################
    (?:(?P<A_Addition_to_address_1>.*?),\s*)? # Addition to address 1
(?:No\.\s*)?
    (?P<A_House_number_1>\pN+[a-zA-Z]?(?:\s*[-\/\pP]\s*\pN+[a-zA-Z]?)*) # House number
\s*,?\s*
    (?P<A_Street_name_1>(?:[a-zA-Z]\s*|\pN\pL{2,}\s\pL)\S[^,#]*?(?<!\s)) # Street name
\s*(?:(?:[,\/]|(?=\#))\s*(?!\s*No\.)
    (?P<A_Addition_to_address_2>(?!\s).*?))? # Addition to address 2
|   #########################################################################
    # Option B: [<Addition to address 1>] <Street name> <House number>      #
    # [<Addition to address 2>]                                             #
    #########################################################################
    (?:(?P<B_Addition_to_address_1>.*?),\s*(?=.*[,\/]))? # Addition to address 1
    (?!\s*No\.)(?P<B_Street_name>\S\s*\S(?:[^,#](?!\b\pN+\s))*?(?<!\s)) # Street name
\s*[\/,]?\s*(?:\sNo\.)?\s+
    (?P<B_House_number>\pN+\s*-?[a-zA-Z]?(?:\s*[-\/\pP]?\s*\pN+(?:\s*[\-a-zA-Z])?)*|[IVXLCDM]+(?!.*\b\pN+\b))(?<!\s) # House number
\s*(?:(?:[,\/]|(?=\#)|\s)\s*(?!\s*No\.)\s*
    (?P<B_Addition_to_address_2>(?!\s).*?))? # Addition to address 2
)
\s*\Z

https://regex101.com/library/lU7gY7

Метод JAVA:

    import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class regEx {
    public static void main( String args[] ) {
          // String to be scanned to find the pattern.
          String line = "Bygholm Søpark 21B";
          String pattern = "\\A\\s*\r\n" + 
                "(?: #########################################################################\r\n" + 
                "    # Option A: [<Addition to address 1>] <House number> <Street name>      #\r\n" + 
                "    # [<Addition to address 2>]                                             #\r\n" + 
                "    #########################################################################\r\n" + 
                "    (?:(?:P<A_Addition_to_address_1>.*?),\\s*)? # Addition to address 1\r\n" + 
                "(?:No\\.\\s*)?\r\n" + 
                "    (?:P<A_House_number_1>\\pN+[a-zA-Z]?(?:\\s*[-\\/\\pP]\\s*\\pN+[a-zA-Z]?)*) # House number\r\n" + 
                "\\s*,?\\s*\r\n" + 
                "    (?:P<A_Street_name_1>(?:[a-zA-Z]\\s*|\\pN\\pL{2,}\\s\\pL)\\S[^,#]*?(?<!\\s)) # Street name\r\n" + 
                "\\s*(?:(?:[,\\/]|(?=\\#))\\s*(?!\\s*No\\.)\r\n" + 
                "    (?:P<A_Addition_to_address_2>(?!\\s).*?))? # Addition to address 2\r\n" + 
                "|   #########################################################################\r\n" + 
                "    # Option B: [<Addition to address 1>] <Street name> <House number>      #\r\n" + 
                "    # [<Addition to address 2>]                                             #\r\n" + 
                "    #########################################################################\r\n" + 
                "    (?:(?:P<B_Addition_to_address_1>.*?),\\s*(?=.*[,\\/]))? # Addition to address 1\r\n" + 
                "    (?:!\\s*No\\.)(?:P<B_Street_name>\\S\\s*\\S(?:[^,#](?!\\b\\pN+\\s))*?(?:<!\\s)) # Street name\r\n" + 
                "\\s*[\\/,]?\\s*(?:\\sNo\\.)?\\s+\r\n" + 
                "    (?:P<B_House_number>\\pN+\\s*-?[a-zA-Z]?(?:\\s*[-\\/\\pP]?\\s*\\pN+(?:\\s*[\\-a-zA-Z])?)*|[IVXLCDM]+(?!.*\\b\\pN+\\b))(?<!\\s) # House number\r\n" + 
                "\\s*(?:(?:[,\\/]|(?=\\#)|\\s)\\s*(?!\\s*No\\.)\\s*\r\n" + 
                "    (?:P<B_Addition_to_address_2>(?!\\s).*?))? # Addition to address 2\r\n" + 
                ")\r\n" + 
                "\\s*\\Z";

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

          // Now create a matcher object.
          Matcher m = r.matcher(line);
          if (m.find( )) {
             System.out.println("B_Street_name: " + m.group(1) );
             System.out.println("B_House_number: " + m.group(2) );
             System.out.println("B_Addition_to_address_2: " + m.group(3) );
          }else {
             System.out.println("NO MATCH");
          }
       }
}

Ответы [ 2 ]

1 голос
/ 09 мая 2019

Есть много вещей, которые нужно иметь в виду.

  • Именованные группы захвата : там синтаксис в Java (?<name>pattern), а имена могут состоять только из цифр или букв ASCII (см. Я не могу использовать имя группы, подобное этому "abc_def" используя Patterns ). Заменить все (?P<name_parts>...) на (?<nameparts>...)
  • Использование #: во многих разновидностях, кроме Java, режим свободного пробела позволяет использовать литерал # внутри классов символов без экранирования. В Java любые значимые пробелы и # ДОЛЖНЫ быть экранированы ДАЖЕ внутри классов символов (замените все # на \\# внутри классов символов и шаблона).
  • Pattern.COMMENTS используется в Java для включения режима свободного пробела / комментария. Либо добавьте (?x) в начале шаблона.

Вот ваш код исправления:

String line = "Bygholm Søpark 21B";
String pattern = "\\A\\s*\r\n" + 
  "(?: #########################################################################\r\n" + 
  "    # Option A: [<Addition to address 1>] <House number> <Street name>      #\r\n" + 
  "    # [<Addition to address 2>]                                             #\r\n" + 
  "    #########################################################################\r\n" + 
  "    (?:(?<AAdditiontoaddress1>.*?),\\s*)?         # Addition to address 1\r\n" + 
  "(?:No\\.\\s*)?\r\n" + 
  "    (?<AHousenumber1>\\pN+[a-zA-Z]?(?:\\s*[-/\\pP]\\s*\\pN+[a-zA-Z]?)*) # House number\r\n" + 
  "\\s*,?\\s*\r\n" + 
  "    (?<AStreetname1>(?:[a-zA-Z]\\s*|\\pN\\pL{2,}\\s\\pL)\\S[^,\\#]*?(?<!\\s)) # Street name\r\n" + 
  "\\s*(?:(?:[,/]|(?=\\#))\\s*(?!\\s*No\\.)\r\n" + 
  "    (?<AAdditiontoaddress2>(?!\\s).*?))?              # Addition to address 2\r\n" + 
  "|   #########################################################################\r\n" + 
  "    # Option B: [<Addition to address 1>] <Street name> <House number>      #\r\n" + 
  "    # [<Addition to address 2>]                                             #\r\n" + 
  "    #########################################################################\r\n" + 
  "    (?:(?<BAdditiontoaddress1>.*?),\\s*(?=.*[,/]))?   # Addition to address 1\r\n" + 
  "    (?!\\s*No\\.)(?<BStreetname>\\S\\s*\\S(?:[^,\\#](?!\\b\\pN+\\s))*?(?<!\\s)) # Street name\r\n" + 
  "\\s*[/,]?\\s*(?:\\sNo\\.)?\\s+\r\n" + 
  "    (?<BHousenumber>\\pN+\\s*-?[a-zA-Z]?(?:\\s*[-/\\pP]?\\s*\\pN+(?:\\s*[-a-zA-Z])?)*|[IVXLCDM]+(?!.*\\b\\pN+\\b))(?<!\\s) # House number\r\n" + 
  "\\s*(?:(?:[,/]|(?=\\#)|\\s)\\s*(?!\\s*No\\.)\\s*\r\n" + 
  "    (?<BAdditiontoaddress2>(?!\\s).*?))? # Addition to address 2\r\n" + 
  ")\r\n" + 
  "\\s*\\Z";

// Create a Pattern object
Pattern r = Pattern.compile(pattern, Pattern.COMMENTS);
// Now create a matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
    System.out.println("B_Street_name: " + m.group("BStreetname") );
    System.out.println("B_House_number: " + m.group("BHousenumber") );
    System.out.println("B_Addition_to_address_2: " + m.group("BAdditiontoaddress2") );
} else {
    System.out.println("NO MATCH");
}

См. Java демо онлайн .

Выход:

B_Street_name: Bygholm Søpark
B_House_number: 21B
B_Addition_to_address_2: null
0 голосов
/ 08 мая 2019

Я не совсем уверен, в чем может быть ваша проблема, так как ваше выражение лица работает нормально. Однако, кажется, у вас есть много границ в вашем RegEx, которые вы, возможно, захотите тщательно СУХОЙ с большими выборками набора данных.

Если вы хотите СУШИТЬ, прежде чем сменить его на c #, вы можете разместить вопрос здесь , возможно, кто-то поможет вам в этом.

Тест с (C #)

using System;
using System.Text.RegularExpressions;

public class Example
{
    public static void Main()
    {
        string pattern = @"\A\s*
(?: #########################################################################
    # Option A: [<Addition to address 1>] <House number> <Street name>      #
    # [<Addition to address 2>]                                             #
    #########################################################################
    (?:(?P<A_Addition_to_address_1>.*?),\s*)? # Addition to address 1
(?:No\.\s*)?
    (?P<A_House_number_1>\pN+[a-zA-Z]?(?:\s*[-\/\pP]\s*\pN+[a-zA-Z]?)*) # House number
\s*,?\s*
    (?P<A_Street_name_1>(?:[a-zA-Z]\s*|\pN\pL{2,}\s\pL)\S[^,#]*?(?<!\s)) # Street name
\s*(?:(?:[,\/]|(?=\#))\s*(?!\s*No\.)
    (?P<A_Addition_to_address_2>(?!\s).*?))? # Addition to address 2
|   #########################################################################
    # Option B: [<Addition to address 1>] <Street name> <House number>      #
    # [<Addition to address 2>]                                             #
    #########################################################################
    (?:(?P<B_Addition_to_address_1>.*?),\s*(?=.*[,\/]))? # Addition to address 1
    (?!\s*No\.)(?P<B_Street_name>\S\s*\S(?:[^,#](?!\b\pN+\s))*?(?<!\s)) # Street name
\s*[\/,]?\s*(?:\sNo\.)?\s+
    (?P<B_House_number>\pN+\s*-?[a-zA-Z]?(?:\s*[-\/\pP]?\s*\pN+(?:\s*[\-a-zA-Z])?)*|[IVXLCDM]+(?!.*\b\pN+\b))(?<!\s) # House number
\s*(?:(?:[,\/]|(?=\#)|\s)\s*(?!\s*No\.)\s*
    (?P<B_Addition_to_address_2>(?!\s).*?))? # Addition to address 2
)
\s*\Z";
        string input = @"Corso XXII Marzo 69";
        RegexOptions options = RegexOptions.IgnorePatternWhitespace;

        Match m = Regex.Match(input, pattern, options);
        Console.WriteLine("'{0}' found at index {1}", m.Value, m.Index);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...