我正在尝试编写一个函数,从包含某个子字符串的句子中提取每个单词,例如在'Porky Pork Chop'寻找'Po'将返回Porky Pork。
我在regexpal上测试了我的正则表达式,但Java代码似乎不起作用。我做错了什么?
private static String foo()
{
String searchTerm = "Pizza";
String text = "Cheese Pizza";
String sPattern = "(?i)\b("+searchTerm+"(.+?)?)\b";
Pattern pattern = Pattern.compile ( sPattern );
Matcher matcher = pattern.matcher ( text );
if(matcher.find ())
{
String result = "-";
for(int i=0;i < matcher.groupCount ();i++)
{
result+= matcher.group ( i ) + " ";
}
return result.trim ();
}else
{
System.out.println("No Luck");
}
}
答案 0 :(得分:3)
在Java中将\b
word boundaries传递给regex引擎,您需要将其写为\\b
。 \b
表示String对象中的退格。
根据您的示例判断,您希望返回包含子字符串的所有单词。要执行此操作,请不要使用for(int i=0;i < matcher.groupCount ();i++)
,而是使用while(matcher.find())
,因为组计数将在单个匹配中迭代所有组,而不是在所有匹配上。
如果您的字符串可以包含一些特殊字符,您可能应该使用Pattern.quote(searchTerm)
在您的代码中,您试图在"Pizza"
中找到"Cheese Pizza"
,因此我假设您还希望找到与搜索到的子字符串相同的字符串。虽然您的正则表达式可以正常使用,但您可以将上一部分(.+?)?)
更改为\\w*
,并在开头添加\\w*
,如果子字符串也应该在单词的中间匹配(不仅在开始)。
所以你的代码看起来像
private static String foo() {
String searchTerm = "Pizza";
String text = "Cheese Pizza, Other Pizzas";
String sPattern = "(?i)\\b\\w*" + Pattern.quote(searchTerm) + "\\w*\\b";
StringBuilder result = new StringBuilder("-").append(searchTerm).append(": ");
Pattern pattern = Pattern.compile(sPattern);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
result.append(matcher.group()).append(' ');
}
return result.toString().trim();
}
答案 1 :(得分:2)
虽然正则表达式方法当然是一种有效的方法,但我发现当你用空格分割单词时更容易思考。这可以使用String
的{{3}}方法完成。
public List<String> doIt(final String inputString, final String term) {
final List<String> output = new ArrayList<String>();
final String[] parts = input.split("\\s+");
for(final String part : parts) {
if(part.indexOf(term) > 0) {
output.add(part);
}
}
return output;
}
当然,实现这一目标实际上是通过输入String进行两次传递是没有价值的。第一个找到要拆分的空格的字符,第二个遍读查看子字符串的每个拆分字。
如果需要一次通过,则正则表达式路径更好。
答案 2 :(得分:1)
我发现 nicholas.hauschild 的答案是最好的。
但是如果你真的想使用正则表达式,你可以这样做:
String searchTerm = "Pizza";
String text = "Cheese Pizza";
Pattern pattern = Pattern.compile("\\b" + Pattern.quote(searchTerm)
+ "\\b", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(matcher.group());
}
输出:
Pizza
答案 3 :(得分:1)
模式应该是
String sPattern = "(?i)\\b("+searchTerm+"(?:.+?)?)\\b";
您想要捕获整个(披萨)字符串。?:
确保您不会捕获字符串的一部分两次。
答案 4 :(得分:0)
尝试这种模式:
String searchTerm = "Po";
String text = "Porky Pork Chop oPod zzz llPo";
Pattern p = Pattern.compile("\\p{Alpha}+" + substring + "|\\p{Alpha}+" + substring + "\\p{Alpha}+|" + substring + "\\p{Alpha}+");
Matcher m = p.matcher(myString);
while(m.find()) {
System.out.println(">> " + m.group());
}
答案 5 :(得分:0)
好的,我给你一个原始风格的模式(不是java风格,你必须自己双倍逃避):
(?i)\b[a-z]*po[a-z]*\b
这就是全部。