Java разбора строки с использованием регулярных выражений в переменные - PullRequest
0 голосов
/ 06 декабря 2018

Мне нужно извлечь переменные из строки.

String format = "x:y";
String string = "Marty:McFly";

Затем

String x = "Marty";
String y = "McFly";

, но форматом может быть все, что может выглядеть следующим образом: y? X => McFly? Marty

Как решить эту проблему с помощью регулярных выражений?

Редактировать: текущее решение

        String delimiter = format.replace(Y, "");
        delimiter = delimiter.replaceAll(X, "");
        delimiter = "\\"+delimiter;

        String strings[] = string.split(delimiter);

        String x; 
        String y;
        if(format.startsWith(X)){
             x = strings[0];
             y = strings[1];
        }else{
             y = strings[0];
             x = strings[1];
        }

        System.out.println(x);
        System.out.println(y);

Это работает хорошо, но я бы предпочел более чистое решение.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Вы можете использовать следующее регулярное выражение (\\w)(\\W)(\\w)

При этом будут найдены любые буквенно-цифровые символы, за которыми следует любой не буквенно-цифровой символ, за которым следует другой набор буквенно-цифровых символов.Круглые скобки сгруппируют результаты, так что группа 1 будет параметром 1, группа 2 будет разделителем, а группа 3 будет параметром 2.

Сравнение параметра 1 с параметром 2 может определить, в каком лексическом порядке они идут.

Образец

  public static void main(String[] args)  {
    testString("x:y", "Marty:McFly");
    testString("x?y", "Marty?McFly");
    testString("y:x", "Marty:McFly");
    testString("y?x", "Marty?McFly");
  }

  /**
   * 
   */
  private static void testString(String format, String string) {
    String regex = "(\\w)(\\W)(\\w)";

    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(format);

    if (!matcher.find()) throw new IllegalArgumentException("no match found");

    String delimiter = matcher.group(2);

    String param1 = matcher.group(1); 
    String param2 = matcher.group(3); 


    String[] split = string.split("\\" + delimiter);
    String x;
    String y;
    switch(param1.compareTo(param2)) {
      case 1:
        x = split[1];
        y = split[0];
        break;
      case -1:
      case 0:
      default:
        x = split[0];
        y = split[1];
    };

    System.out.println("String x: " + x);
    System.out.println("String y: " + y);

    System.out.println(String.format("%s%s%s", x, delimiter, y));
    System.out.println();
  }

Этот подход позволит вам использовать любой тип формата, а не только x и y.Вы можете иметь любой формат, соответствующий регулярному выражению.

0 голосов
/ 06 декабря 2018

Нет необходимости в регулярных выражениях.

public static void main(String[] args) {
    test("x:y", "Marty:McFly");
    test("y?x", "McFly?Marty");
}
public static void test(String format, String input) {
    if (format.length() != 3 || Character.isLetterOrDigit(format.charAt(1))
                             || (format.charAt(0) != 'x' || format.charAt(2) != 'y') &&
                                (format.charAt(0) != 'y' || format.charAt(2) != 'x'))
        throw new IllegalArgumentException("Invalid format: \"" + format + "\"");
    int idx = input.indexOf(format.charAt(1));
    if (idx == -1 || input.indexOf(format.charAt(1), idx + 1) != -1)
        throw new IllegalArgumentException("Invalid input: \"" + input + "\"");
    String x, y;
    if (format.charAt(0) == 'x') {
        x = input.substring(0, idx);
        y = input.substring(idx + 1);
    } else {
        y = input.substring(0, idx);
        x = input.substring(idx + 1);
    }
    System.out.println("x = " + x);
    System.out.println("y = " + y);
}

Вывод

x = Marty
y = McFly
x = Marty
y = McFly

Если строку формата можно изменить наregex, затем использование именованных групп захвата сделает это очень простым:

public static void main(String[] args) {
    test("(?<x>.*?):(?<y>.*)", "Marty:McFly");
    test("(?<y>.*?)\\?(?<x>.*)", "McFly?Marty");
}
public static void test(String regex, String input) {
    Matcher m = Pattern.compile(regex).matcher(input);
    if (! m.matches())
        throw new IllegalArgumentException("Invalid input: \"" + input + "\"");
    String x = m.group("x");
    String y = m.group("y");
    System.out.println("x = " + x);
    System.out.println("y = " + y);
}

Тот же вывод, что и выше, включая порядок значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...