是否可以制作修改后的模式,以便在应用拆分时,分隔符将是与基本模式不匹配的任何内容?

时间:2012-07-19 17:41:52

标签: java regex string split

String.split()的最近一次使用中,我遇到的情况是文本非常动态,比较过滤不匹配更容易获取匹配。

我发现自己想知道是否可以为String.split()修改“反向正则表达式”,以便您可以为其指定任何模式,并且它将匹配与该模式不匹配的每组字符。

*注意:此处的“问题”可以通过String.matches()TokensMatcher.group()等轻松解决。此问题主要是假设的(代码示例)仍然是受欢迎的,因为问题的本质非常需要它),并且不是关于如何实现结果,而是关于如果它可以以这种方式实现它们


我尝试了什么:

String pattern1 = "(test)"; //A verif. that what "should-not-match" is working correctly.
        String pattern2 = "[^(test)]"; //FAIL - unmatches the letters separately.
        String pattern3 = "(^(test))"; //FAIL - does not match anything, it seems.
        String text = ""
                        + "This is a test. "
                        + "This test should (?not?) match the word \"test\", whenever it appears.\n"
                        + "This is about to test if a \"String.split()\" can be used in a different way.\n"
                        + "By the way, \"testing\" does not equal \"test\","
                        + "but it will split in the middle because it contains \"test\".";
        for (String s : text.split(pattern3)) {
            System.out.println(s);
        }

和其他类似的模式一样,其中没有任何一个接近成功。


更新:

我现在也尝试使用特殊构造函数的一些模式,但是它们也没有使用它。

关于我想要的,在“测试”示例之后,是获取一个包含内容为“text”的字符串的数组(我想用作基本模式,或者换句话说我想要查找的内容)。

但是这样做是使用String.split(),使得使用基本模式直接导致“无论什么不是(测试)”,因此需要反转以便“只发生(测试)”。< / p>

圣经大小 - 长篇故事短片,想要的是String.split()的正则表达式导致此行为(+结果): 注意:遵循上面的示例代码,包括所需的变量(文本)。

String[] trash = text.split("test"); //<-base pattern, needs reversing.
        System.out.println("\n\nWhat should match the split-pattern (due reversal), become separators, and be filtered out:");
        for (String s : trash) {
            System.out.println("[" + s + "]");
            text = text.replace(s, "%!%"); //<-simulated wanted behavior.
        }
        System.out.println("\n\nWhat should be the resulting String[]:");
        for (String s : text.split("%!%")) {
            System.out.println(s);
        }
        System.out.println("Note: There is a blank @ index [0], since if the text does not start with \"test\", there is a sep. between. This is NOT WRONG.");

欢迎使用代码示例。毕竟创建这样的代码的可能性(或不是)是这个问题的本质。

2 个答案:

答案 0 :(得分:3)

你可能在谈论(?!construct。

它在Pattern类的javadoc中有记录。他们称之为负面的前瞻性断言。

解决问题最直接的方法是重复查找。

    Pattern p = Pattern.compile(regexForThingIWant);
    Matcher m = p.matcher(str);
    int cursor = 0;
    while (m.find(cursor)) {
      String x = m.group();
      // do something with x
      cursor = m.end();
    }

我能够克服正则表达式,看起来像你想做的那样,但很糟糕:

(^|(?<=test))((?!test).)*

答案 1 :(得分:0)

我很难看到你想看到的split的输出,因为你的唯一提示是测试字符串的一部分,然后只是间接的(就像你想要的那样{{1}分两部分出来。)

好吧,让我们尝试一下积​​极的看法:

testing

返回

^|(?<=test)

这就是你想要的吗?

请注意,在分割文本时,分割过程不会消耗输入的“匹配”和“非匹配”位(松散意义上),您需要设计正则表达式,以便它只匹配(一些)空字符串,在技术意义上的“匹配”一词。

因此,Lookaheads和lookbehinds几乎只是使用正则表达式解决此类任务的唯一工具。

但是,如果您希望消耗所有非测试部件,那也是可以实现的。

This is a test
. This test
 should (?not?) match the word "test
", whenever it appears.
This is about to test
 if a "String.split()" can be used in a different way.
By the way, "test
ing" does not equal "test
",but it will split in the middle because it contains "test
".

这是相同的外观,然后消耗任何看起来不像单词(?<=^|(test))(tes[^t]|te[^s]|t[^e]|[^t])* 的东西。

但这种方法并不完全通用。 This question解释了这些限制。