Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字符串#replaceAll()替换*除a=*组以外的任何对象_Java_Regex_String_Replace_Replaceall - Fatal编程技术网

Java 字符串#replaceAll()替换*除a=*组以外的任何对象

Java 字符串#replaceAll()替换*除a=*组以外的任何对象,java,regex,string,replace,replaceall,Java,Regex,String,Replace,Replaceall,我有一个键值参数,如下所示: sign="aaaabbbb=" 我想得到参数名符号和值“aaaabbb=“(带引号符号) 我想我可以用=拆分字符串,以获取数组的第一个元素,即参数名,然后执行string.replaceAll()以删除符号=以获取值。无论如何,以下是我的示例代码: public class TestStringReplace { public static void main(String[] argvs){ String s = "sign=\"aaa

我有一个键值参数,如下所示:

sign="aaaabbbb="
我想得到参数名
符号
和值
“aaaabbb=“
(带引号符号)

我想我可以用
=
拆分字符串,以获取数组的第一个元素,即参数名,然后执行
string.replaceAll()
以删除
符号=
以获取值。无论如何,以下是我的示例代码:

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="
为什么
\[^=]+=
不匹配
符号=
并在此处用空字符串替换它?Java正则表达式的新手,需要一些帮助


提前感谢。

您最好在这里使用实际的
模式和反向引用

例如:

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="
[sign, aaaabbbb]
[blah?sign, aaaabbbb] --> yuck
[foo?sign, aaaabbbb, &blah, hodor"] --> yuck again
注释

  • 我假设有一个HTTP GET styled参数列表,但您可能不需要实际检查下一个参数键值对分隔符(即
    &
    )-在这种情况下,您可以删除
    &
    部分
  • 假设您希望
    s超出您的返回值引用,这使得下面的
    &
    检查没有用处
  • 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
    组值,因为您正在创建一个新的
    字符串来替换原始字符串

  • 最后一种可能的解决方案是使用
    String#“split
    。这是最难看的,因为它不能很好地处理参数列表:

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

双斜杠是一个错误,因为它将
[
转义为一个永远不会匹配的文本
[

相反,请执行以下操作:

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

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

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=“aaaabbbb=”
,结果是
replaceAll()
,它没有替换任何内容,因为没有匹配项。

在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=“aaaabbb=“

为什么不把你的
split()
限制在
=
的第一次出现,像这样:
s.split(=”,1);
你认为前面的反斜杠在做什么?看看Regex星球,我发现它对Regex问题非常有用:@willOEM确实激发了这个想法,但它应该是
s.split(=”,2)
谢谢:-)试试这个:-字符串值=s.substring(s.indexOf(“\”)+1,s.lastIndexOf(“\”));回答得很好,谢谢,但我有点害怕反向引用的东西,事实上,如果只使用split和其他技巧就可以了,我永远不会给regex反向引用一次机会-D@armnotstrong不客气。在我看来,你不应该害怕一个基本上是为你想要达到的目的而制定的解决方案。很好,谢谢,但我是直到我不知道为什么
[^=]+=
不起作用,我现在知道\\将是转义,但为什么我要匹配
它应该是\\\\”?奇怪:-(为什么不像通常的一些语言那样使用一个\作为转义?@armnotstrong它不起作用,因为
[^=]+=
也将匹配
aaaabbbbb=
并且结果值将是
@armnotstrong我的答案对你有帮助吗?如果有,请接受/投票。注意,
*=
可能不起作用,值中可能有一个
=
符号:-)@armnotstrong正是如此。我已经通过正则表达式进行了修改以适应这一点(使量词不情愿)