Java - 从模式中提取字符串

时间:2015-05-20 17:38:01

标签: java regex

给出一些看起来像这样的字符串:

(((((((((((((4)+13)*5)/1)+7)+12)*3)-6)-11)+9)*2)/8)-10)
(((((((((((((4)+13)*6)/1)+5)+12)*2)-7)-11)+8)*3)/9)-10)
(((((((((((((4)+13)*6)/1)+7)+12)*2)-8)-11)+5)*3)/9)-10)

(顺便说一句,他们是我为其编写程序的谜题的解决方案:))

他们都分享这种模式

"(((((((((((((.)+13)*.)/.)+.)+12)*.)-.)-11)+.)*.)/.)-10)"

对于1个解决方案:如何使用此给定模式获取值? 所以对于第一个解决方案,我会得到一个像这样的集合,列表,数组(无关紧要):

[4,5,1,7,3,6,9,2,8]

1 个答案:

答案 0 :(得分:3)

您通过提供模式实际完成了大部分工作。您需要做的就是使用.所在的捕获组(并逃避其余部分)。

我将您的输入放在String数组中,并将结果转换为List整数(如您所说,您可以将其更改为其他内容)。至于图案,你想捕捉点;这是通过使用()包围它们来完成的。在你的情况下的问题是整个字符串充满了它们,所以我们需要引用/转义它们(意思是,告诉正则表达式编译器我们的意思是文字/字符()) 。这可以通过将我们想要转义的部分放在\Q\E之间来完成。

下面的代码显示了一种连贯(但可能无效)的方法。请注意在正确的位置使用适量的\

public class Example {

    public static void main(String[] args) {

        String[] inputs = new String[3];
        inputs[0] = "(((((((((((((4)+13)*5)/1)+7)+12)*3)-6)-11)+9)*2)/8)-10)";
        inputs[1] = "(((((((((((((4)+13)*6)/1)+5)+12)*2)-7)-11)+8)*3)/9)-10)";
        inputs[2] = "(((((((((((((4)+13)*6)/1)+7)+12)*2)-8)-11)+5)*3)/9)-10)";

        List<Integer> results;

        String pattern = "(((((((((((((.)+13)*.)/.)+.)+12)*.)-.)-11)+.)*.)/.)-10)"; // Copy-paste from your question.
        pattern = pattern.replaceAll("\\.", "\\\\E(.)\\\\Q");
        pattern = "\\Q" + pattern;
        Pattern p = Pattern.compile(pattern);
        Matcher m;

        for (String input : inputs) {
            m = p.matcher(input);
            results = new ArrayList<>();
            if (m.matches()) {
                for (int i = 1; i < m.groupCount() + 1; i++) {
                    results.add(Integer.parseInt(m.group(i)));
                }
            }
            System.out.println(results);
        }
    }
}

输出:

[4, 5, 1, 7, 3, 6, 9, 2, 8]
[4, 6, 1, 5, 2, 7, 8, 3, 9]
[4, 6, 1, 7, 2, 8, 5, 3, 9]

注意:

  • 您正在使用单个.,这意味着

      

    任何字符(可能与行终止符匹配也可能不匹配)

    因此,如果您有一个不是单个数字的数字或不是数字(数字)的单个字符,那么matchesparseInt中就会出现问题。考虑\\d代表单个数字,或者\\d+代表数字。

  • 有关Java中正则表达式的更多信息,请参阅Pattern