我正在寻找一个正则表达式(在Java中使用),以便在以下所有句子中获得以下单词(Peach,Apple)之间的所有3个或更多单词:
Peach are nice fruits. Apple are not.
此时,我正在使用以下部分:
\w{3,}\b
获取所有3个以上字符的单词。我正在使用正面和负面的外观来获取Peach
和Apple
之间的单词:
(?<=Peach).*(?=Apple).
我不能使用两个正则表达式,我不能使用子字符串或任何其他技术。只有一个正则表达式来提取单词。
答案 0 :(得分:3)
您可以在lookbehind中使用\G
:
Pattern p = Pattern.compile("(?<=(?:\\bPeach\\b|\\G)\\W).*?\\b((?!Apple\\b)\\w{3,})\\b");
String msg = "Peach a nice family of fruits. Apple are not.";
Matcher m = p.matcher( msg );
while (m.find()) {
System.out.println( m.group(1) );
}
\G
在上一场比赛结束时或第一场比赛的字符串开头处断言位置。(?<=(?:\\bPeach\\b|\\G)\|W)
会在lookbehind中声明文字"Peach "
或\G
(?!Apple\\b)
将确保完整字Apple
不在当前位置之前\\b\\w{3,}\\b
将匹配0个或更多任意字符后的3个或更多字符的完整单词。<强>输出:强>
nice
family
fruits
如果字符串中有多个Peach和Apple ,那么您可以使用:
String msg = "Peach, a nice family of fruits. Apple are not. Another Peach foo bar is here Apple end.";
Pattern p = Pattern.compile(
"(?:(?<=\\bPeach\\b|\\G)\\W)(?:(?!\\bApple\\b).)*?\\b((?!Apple\\b)\\w{3,})\\b");
Matcher m = p.matcher(msg);
while (m.find()) {
System.out.println(m.group(1));
}
<强>输出强>
nice
family
fruits
foo
bar
here
这个看起来很笨拙的正则表达式可能会处理许多边缘情况,但只有在嵌套/不平衡Peach/Apple
对的要求时才应该使用它:
(?:(?<=\bPeach\b(?!(?:(?!\bApple\b).)*?\bPeach\b)|\G)\W)(?:(?!\bApple\b).)*?\b((?!Apple\b)\w{3,})\b
答案 1 :(得分:0)
您可以分两步完成,而不是编写完成所有工作的单个正则表达式:
这种方法可以简化正则表达式,并且在边缘情况下不易出错。
以下面的字符串为例:
桃子,一个很好的水果家庭苹果不是。另一个Peach foo酒吧就在这里Apple。 Peach里面的Apple Peach然后Apple Peach没有没有Apple
我使用正则表达式(?<=\bPeach\b).*?(?=\bApple\b)
来挑选子字符串
, a nice family of fruits
, foo bar is here
, inside Peach then
, no no
,然后从这些子字符串中提取包含3个或更多字符的字词。
上面的正则表达式只是一个例子。根据您在边缘情况下的要求,您可以自定义正则表达式以仅提取要从中提取单词的子字符串。
您可以将上面的正则表达式更改为(?<=\bPeach\b).*(?=\bApple\b)
,以获取第一个Peach和最后一个Apple之间的所有内容。
上述示例的输出为:
[nice, family, fruits, foo, bar, here, inside, Peach, then]
根据您的需要,您可以按照上面的建议更改正则表达式,或者只是简单地过滤输出。
完整的示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
class SO32415895 {
public static void main(String[] args) {
String input = "Peach, a nice family of fruits Apple are not. Another Peach foo bar is here Apple. Apple Peach inside Peach then Apple Peach no no Apple";
List<String> inBetween = findAll("(?<=\\bPeach\\b).*?(?=\\bApple\\b)", input);
List<String> words = new ArrayList<>();
Pattern WORD_PATTERN = Pattern.compile("\\b\\w{3,}\\b");
for (String s: inBetween) {
words.addAll(findAll(WORD_PATTERN, s));
}
System.out.println(words);
}
public static List<String> findAll(String pattern, String input) throws PatternSyntaxException {
return findAll(Pattern.compile(pattern), input);
}
public static List<String> findAll(Pattern pattern, String input) {
Matcher m = pattern.matcher(input);
List<String> out = new ArrayList<>();
while (m.find()) {
out.add(m.group());
}
return out;
}
}