String#replaceAll()替换*除了a = * group

时间:2015-05-27 15:42:35

标签: java regex string replace replaceall

我有一个像这样的键值参数:

sign="aaaabbbb="

我想获取参数名称sign和值"aaaabbb="(带引号)

我以为我可以使用=拆分字符串以获取数组的第一个元素(参数名称)并执行String.replaceAll()以删除sign=以获取值。无论如何这里是我的示例代码:

public class TestStringReplace {
    public static void main(String[] argvs){
        String s = "sign=\"aaaabbbb=\"";
        String[] ss = s.split("=");
        String value = s.replaceAll("\\[^=]+=","");
        //EDIT:        s.replaceAll("[^=]+=","") will not do the job either.
        System.out.println(ss[0]);
        System.out.println(value);
    }
}

但输出显示:

sign
sign="aaaabbbb="

为什么\\[^=]+=不匹配sign=并将其替换为空字符串?这是Java正则表达式的新手,需要一些帮助。

提前致谢。

4 个答案:

答案 0 :(得分:1)

你可能会更好地使用实际的Pattern和后面的引用。

例如:

String[] test = {
    "sign=\"aaaabbbb=\"",
    // assuming a HTTP GET-styled parameter list
    "blah?sign=\"aaaabbbb=\"",
    "foo?sign=\"aaaabbbb=\"&blah=\"hodor\""
};
//                           | group 1: literal "sign"
//                           |      | literal key-value delimiter and double quote
//                           |      | | group 2: any character reluctantly quantified
//                           |      | |   | literal ending double quote
//                           |      | |   |  | look-ahead for either "&" or end
//                           |      | |   |  | 
Pattern p = Pattern.compile("(sign)=\"(.+?)\"(?=$|&)");
Matcher m = null;
for (String s: test) {
    m = p.matcher(s);
    while (m.find()) {
        System.out.printf(
            "Found key: \"%s\" and value: \"%s\"%n", m.group(1), m.group(2)
        );
    }

}

<强>输出

Found key: "sign" and value: "aaaabbbb="
Found key: "sign" and value: "aaaabbbb="
Found key: "sign" and value: "aaaabbbb="

备注

  • 我假设有一个HTTP GET样式的参数列表,但是你可能不需要实际检查下一个参数键值对分隔符(即&) - 在这种情况下你可以删除{ {1}}部分
  • ,假设您希望&超出您的值返回引用,这使得以下"检查无效
  • &调用的当前模式将匹配如下:

    replaceAll
  • 最后,如果你真的,真的想要使用// | literal "[" (double-escaped) // ||literal "^" or "=" (in character class) // || | ... greedily quantified (1+ occurrences) // || || literal "=" "\\[^=]+=" ,那么这里的模式与上面的模式略有不同:

    String#replaceAll
  • 它仍然使用反向引用并产生相同的结果,虽然方式较为简单:您无法重复使用for (String s: test) { System.out.println( s.replaceAll( ".*(sign)=\"(.+?)\"(?=$|&).*", "Found key: \"$1\" and value: \"$2\"" ) ); } $1组值,因为您正在创建一个新的$2取代原来的。{/ p>

  • 最后一种可能的解决方案,使用String。这是最丑陋的,因为它不适用于参数列表:

    String#'split

    <强>输出

    for (String s: test) {
        System.out.println(
            //                       | negative look-behind for start of input
            //                       |    | literal "="
            //                       |    |  | literal "
            //                       |    |  | 
            Arrays.toString(s.split("(?<!^)=\""))
        );
    }
    

答案 1 :(得分:1)

使用^\\w+=)而不是正则表达式尝试以下正则表达式replaceAll(

public class TestStringReplace {
public static void main(String[] argvs){
    String s = "sign=\"aaaabbbb=\"";
    String[] ss = s.split("=");
    String value = s.replaceAll("^\\w+=","");
    System.out.println(ss[0]);
    System.out.println(value);
}
}

这将删除sign=

您可以在此处看到DEMO

注意,在您的"\\[^=]+="正则表达式中,您试图在正则表达式的开头字面匹配字符[

它解释了为什么sign="aaaabbbb="导致replaceAll()导致{{1}}没有替换任何内容,因为没有匹配。

答案 2 :(得分:1)

在Java中,您可以使用以下内容:

String str = "sign=\"aaaabbbb=\"";
String var1 = str.substring(0, str.indexOf('='));
String var2 = str.substring(str.indexOf('=')+1);
System.out.println("var1="+var1+", var2="+var2);

以上将有以下输出:

var1 = sign,var2 =&#34; aaaabbbb =&#34;

答案 3 :(得分:0)

双斜杠是一个错误,因为它正在将[转移到文字 [,它永远不会匹配。

相反,这样做:

String name = s.replaceAll("=.*", "");
String value = s.replaceAll(".*?=", "");