java使用regex将字符串解析为变量

zf2sa74q  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(365)

我需要从字符串中提取变量。

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

然后

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

但是格式可以是任何东西,它可以看起来像这个y?x=>mcfly?marty
如何使用regex解决这个问题?
编辑:当前解决方案

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);

这很管用,但我更喜欢干净的溶液。

nom7f22z

nom7f22z1#

您可以使用以下正则表达式 (\\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。可以有任何与正则表达式匹配的格式。

68bkxrlz

68bkxrlz2#

根本不需要regex。

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);
}

与上述输出相同,包括值顺序。

相关问题