2013-10-23 165 views
1

我想做一个startStr.replaceAll(searchStr,replaceStr),我有两个要求。替换可能包含正则表达式的整个标记

  1. searchStr必须是一个整个单词,这意味着它必须有一个空格,字符串的开头或字符串的结尾。
    • 例如
      • startStr = “中进行确认,把你的帽子”
      • 字符串searchstr = “ON”
      • 项replacestr = “”
      • 预期= “确认,把你的帽子”
  2. searchStr可能包含一个正则表达式
    • eg
      • startStr = “删除此*事”
      • 字符串searchstr = “*”
      • 项replacestr = “”
      • 预期= “删除这个事情”

对于要求1,我发现这个工程:

startStr.replaceAll("\\b"+searchStr+"\\b",replaceStr)

对于需要2,我发现这工作:

startStr.replaceAll(Pattern.quote(searchStr), replaceStr)

但我不能让他们一起工作:

startStr.replaceAll("\\b"+Pattern.quote(searchStr)+"\\b", replaceStr)

这里是简单测试用例失败

startStr = "remove this * thing but not this*"

searchStr = "*"

replaceStr = ""

expected = "remove this thing but not this*"

actual = "remove this * thing but not this*"

我缺少什么?

在此先感谢

+0

我接受下面的答案被@zdanzig。 – kane

+0

但我应该注意到我必须做一个额外的改变。 (\\ s | $)“,”“)只会替换第一个ON。 我结束了使用replaceFirst()和循环来取代所有。 – kane

回答

1

首先,在\ b或单词边界,也不会为你工作的星号。原因是\ b仅检测单词字符的边界。正则表达式解析器不会将*确认为单词字符,因此以正则表达式开头或结尾的通配符单词不会被有效的单词边界包围。

参考页: http://www.regular-expressions.info/wordboundaries.html http://docs.oracle.com/javase/tutorial/essential/regex/bounds.html

你可能会喜欢的一个选项是在正则表达式来提供通配符排列:

(?<=\s|^)(ON|\*N|O\*|\*)(?=\s|$) 

这里有一个Java的例子:

import java.util.regex.Pattern; 
import java.util.regex.Matcher; 

class RegExTest 
{ 
    public static void main(String[] args){ 
    String sourcestring = "ON cONfirmation, put * your hat"; 
    sourcestring = sourcestring.replaceAll("(?<=\\s|^)(ON|\\*N|O\\*|\\*)(?=\\s|$)","").replaceAll(" "," ").trim(); 
    System.out.println("sourcestring=["+sourcestring+"]"); 
    } 
} 

你可以编写一个小函数来自动生成通配符排列。我承认我对这些空间有点不满,但我不认为这是必需的。

发挥与它的在线浏览:http://ideone.com/7uGfIS

+0

是的,我读了一些关于单词的界限。我希望能有一个更简单的答案。这可能是正确的答案。我会稍微等一下,看看其他人是否有另一种解决方案,但可能会在早上接受这是正确的答案 – kane

+0

嗯,它肯定会变得更简单,只需'(?<= \ s | ^)(ON | \ *)(?= \ s | $)'并且没有“排列生成”,如果你不需要部分通配符。 – sdanzig

0

试试这个,

为了去除"ON"

 StringBuilder stringBuilder = new StringBuilder(); 
     String[] splittedValue = startStr.split(" "); 
     for (String value : splittedValue) 
     { 
      if (!value.equalsIgnoreCase("ON")) 
      { 
       stringBuilder.append(value); 
       stringBuilder.append(" "); 
      } 
     } 
     System.out.println(stringBuilder.toString().trim()); 

为了去除"*"

String startStr1 = "remove this * thing"; 
    System.out.println(startStr1.replaceAll("\\*[\\s]", "")); 
1

"\\b"一个字边界相一致的模式,用一个字字符在一个另一方面是ide和一个非单词字符。 *不是一个单词字符,所以\\b\\*\\b将无法​​正常工作。后视和前视匹配,但不消耗模式。您可以指定字符串或空白的开头必须拿出你的图在该空白字符或字符串的结尾必须遵循:

startStr.replaceAll("(?<=^|\\s)"+Pattern.quote(searchStr)+"(?=\\s|$)", replaceStr) 
0

可以使用(^|)\*(|$),而不是使用\\b

试试这个startStr.replaceAll("(^|)youSearchString(|$)", replaceStr);