在String.split()
的最近一次使用中,我遇到的情况是文本非常动态,比较过滤不匹配更容易获取匹配。
我发现自己想知道是否可以为String.split()
修改“反向正则表达式”,以便您可以为其指定任何模式,并且它将匹配与该模式不匹配的每组字符。
*注意:此处的“问题”可以通过String.matches()
,Tokens
,Matcher.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.");
欢迎使用代码示例。毕竟创建这样的代码的可能性(或不是)是这个问题的本质。
答案 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解释了这些限制。