用反斜杠转义一个字符

时间:2014-07-28 05:06:15

标签: java regex

我有一些保留关键字:

+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /

如果在字符串中找到任何这些字符,则应使用前导反斜杠进行转义,例如字符串(1+1)=2

输出应为\(1\+1\)=2

我怎么能在java中做到这一点?

5 个答案:

答案 0 :(得分:1)

试试这个:

String[] splstrings = {...}; //Your special characters here

String input = "(1+1)=2";

for (String s : splstrings)
{
 input = input.replace(s,"\\"+s);
}

正如评论中指出的那样,Replace就是你所需要的。

答案 1 :(得分:1)

    public static void main(String[] args) throws InterruptedException
    {
        String toBeEscaped = "+-&&||!(){}[]^\"~*?:\\/";
        String input = "(1+1)=2";
        StringBuffer outBuffer = new StringBuffer();
        for (int i = 0; i < input.length(); i++)
        {
            if (toBeEscaped.indexOf((int)input.charAt(i))>-1)
            {
                outBuffer.append("\\");
            }
            outBuffer.append(input.charAt(i));
        }

        System.out.println("Input :"+input);
        System.out.println("Output:"+outBuffer);
    }

答案 2 :(得分:0)

大多数是单个字符,但有些(“&amp;&amp;”和“||”)不是。最有效的方法(但也许不是最干净的解决方案)是简单地解析字符串并根据需要替换字符。以下假设每个特殊序列都是单个字符(因此,此解决方案 不适用于“&amp;&amp;”或“||”:

private static final  StringBuilder sb = new StringBuilder();
// this needs to be synchronized because I'm reusing sb
public synchronized static String replace(final String str){
    // clear out your StringBuilder
    sb.delete(0, sb.length());

    for(final char c : str.toCharArray()){
        if(isSpecial(c))
            sb.append('\\');
        sb.append(c);
    }
    return sb.toString();
}

public static boolean isSpecial(final char c){
    switch(c){
    case '+': 
    case '-': 
    case '!': 
    case '(': 
    case ')': 
    case '{': 
    case '[': 
    case ']':
    case '^':
    case '"':
    case '~':
    case '*':
    case '?':
    case ':':
    case '\\':
    case '/': return true;
    }
    // default (i.e. nothing was recognized) this ins't a special character.
    return false
}

处理“&amp;&amp;”之类的事情和“||” (我假设你想要成为“\&amp;&amp;”和“\ ||” - 如果没有,那么上面的工作正常),那么你的isSpecial方法应该采用String的位置并测试它是否包含两个特殊字符。

要处理两个双字符,我会做以下(再次,也许不是最优雅的解决方案 - 但肯定是最有效的):

private static final StringBuilder sb = new StringBuilder();

// this needs to be synchronized because I'm reusing sb
public synchronized static String replace(final String str){
    // clear out your StringBuilder
    sb.delete(0, sb.length());
    final char[] strArray = str.toCharArray();

    for(int i = 0; i < strArray.length; ++i)
        i = processChar(strArray, i);

    return sb.toString();
}

// this should only be called by the replace method--hence why it is private and not
//    and not public--it requires accessing StringBuilder sb in a synchronized way.
private static boolean processChar(final char[] strArray, final int i){
    final char c = strArray[i];
    switch(c){
    case '+': 
    case '-': 
    case '!': 
    case '(': 
    case ')': 
    case '{': 
    case '[': 
    case ']':
    case '^':
    case '"':
    case '~':
    case '*':
    case '?':
    case ':':
    case '\\':
    case '/': 
        sb.append('\\');
        sb.append(c);
        return i;
    }

    // check for double char sequences:
    if(c == '&'){
        final int nextI = i + 1;
        char nextC;
        if(nextI < strArray.length && (nextC = strArray[nextI]) == '&'){
            sb.append('\\');
            sb.append('&&');
            return nextI;
        }
    }
    // else
    if(c == '|'){
        final int nextI = i + 1;
        char nextC;
        if(nextI < strArray.length && (nextC = strArray[nextI]) == '|'){
            sb.append('\\');
            sb.append('||');
            return nextI;
        }
    }        
    // default (i.e. nothing was recognized) this ins't a special character
    // so just print the character to sb and return i
    sb.append(c);
    return i;
}

答案 3 :(得分:0)

这也有效:

    String str = "+ - && || ! ( ) { } [ ] ^ \" ~ * ? : \\ /";
    System.out.println(str.replaceAll("(([+!\\(\\)\\{\\}\\[\\]\\^\"~*?:\\/-])|(\\|\\|)|(&&))", "\\\\$1"));

收益率(打印时,其他\的额外\面临转义:

\+ \- \&& \|| \! \( \) \{ \} \[ \] \^ \" \~ \* \? \: \ \/

因此:

    String str = "(1 + 1) = 2";
    System.out.println(str.replaceAll("(([+!\\(\\)\\{\\}\\[\\]\\^\"~*?:\\/-])|(\\|\\|)|(&&))", "\\\\$1"));

你明白了:

    \(1 \+ 1\) = 2

.replaceAll将正则表达式作为第一个参数,将替换字符串作为第二个参数。如果第一个参数具有正则表达式组(用圆括号表示),则可以通过$运算符后跟组号在替换字符串中访问此类组。这些组从1开始,第0组是整个匹配。

我提供的正则表达式的工作示例和说明可用here

答案 4 :(得分:0)

考虑到您的澄清,您希望&&成为\&&||成为\||,此代码将为您提供帮助:

    String input = "blah && foo + 5 || lala & 3 | 1";

    Pattern pattern = Pattern.compile("([+\\-!(){}\\[\\]^\"~*?:\\\\/]|&&|\\|\\|)");
    Matcher m = pattern.matcher(input);
    String result = m.replaceAll("\\\\$1");

    // Or shorter:

    String result = input.replaceAll("([+\\-!(){}\\[\\]^\"~*?:\\\\/]|&&|\\|\\|)", "\\\\$1");

    // However a Pattern object is re-usable and doesn't incur the overhead 
    // of parsing the regex every time that you use it

    System.out.println("Result: " + result);

我担心正则表达式难以阅读,因为所有反斜杠都会逃避,但确实有效。

输出:

Result: blah \&& foo \+ 5 \|| lala & 3 | 1

注意:如果你真的想做一些疯狂的事情,这会使维护特殊字符列表变得更加容易,那么用这段代码替换行Pattern pattern = ...,这代码动态构建正则表达式:

    String special = "+ - && || ! ( ) { } [ ] ^ \" ~ * ? : \\ /";
    StringBuilder p = new StringBuilder();
    p.append("(");
    for (String s : special.split("\\s")) {
        if (p.length() > 1)
            p.append('|');
        p.append(Pattern.quote(s));
    }
    p.append(")");

    Pattern pattern = Pattern.compile(p.toString());