最佳方法是如何分割包含问号和等号的字符串。

5

我遇到了一个问题,我有一个Java字符串:

String aString="name==p==?header=hello?aname=?????lname=lastname";

我需要在问号后面跟等号处进行分割。
结果应该是键/值对:
name = "=p=="
header = "hello"
aname = "????"
lname = "lastname"

问题在于aname和lname变成了:
name = ""
lname = "????lname=lastname"

我的代码使用aString.split("\\?",2)进行分割,它将返回两个字符串。其中一个包含键/值对,而第二个字符串则包含其余的内容。如果我在字符串中找到问号,我将在第二个字符串上递归,以进一步分解它。

private String split(String aString)
 {
    System.out.println("Split: " + aString);
    String[] vals = aString.split("\\?",2);
    System.out.println("  - Found: " + vals.length);
    for ( int c = 0;c<vals.length;c++ )
       {
        System.out.println("  - "+ c + "| String: [" + vals[c] + "]" );
        if(vals[c].indexOf("?") > 0 )
          {
            split(vals[c]);
           }
        }
    return ""; // For now return nothing...
 }

你有什么想法,如何允许输入姓名中的“?”字符?
免责声明:是的,我的正则表达式技能很低,所以我不知道是否可以通过正则表达式来完成此操作。


1
为什么 p 没有被提取为键? - Evan Knowles
@Evan 说得有道理。你知道这些键(name、header、aname、lname)是始终相同还是来自特定的集合吗? - chickenpie
最终它会变成这样。但现在,我正在尝试在问号上进行拆分。当我在那些地方拆分时,我最终得到一个字符串“name==p==”,然后我将其拆分("\=",2),这样就可以得到键/值对了。 - Multiplexor
问题出在您的输入上。您不应该使用那些也是特殊字符的字符(在您的情况下是 =?)。如果您需要这些字符作为键名或值,您应该对它们进行转义,例如 name=&#61;p&#61;&#61;?header=hello?aname=&#63;&#63;&#63;&#63;?lname=lastname - Absurd-Mind
@Multiplexor 什么意思?如果您能在输入时引发异常,那么您也应该能够正确编码您的URL(我假设这些是URL字符串)。请参阅URLEncoder.encode()此问题以获取更多信息。 - Absurd-Mind
显示剩余2条评论
4个回答

8
你可以让正则表达式处理所有繁重的工作,首先将字符串分成一对对的:

String[] pairs = aString.split("\\?(?!\\?)");

那个正则表达式的意思是“一个 ? 后面没有跟着一个 ?”,它的含义是:
[name==p==, header=hello, aname=????, lname=lastname]

为了把结果分割成名称/值对,只需分割第一个“=”即可:
String[] split = pair.split("=", 2); // max 2 parts

将所有内容综合起来:

String aString = "name==p==?header=hello?aname=?????lname=lastname";
for (String pair : aString.split("\\?(?!\\?)")) {
    String[] split = pair.split("=", 2);
    System.out.println(split[0] + " is " + split[1]);
}

输出:

name is =p==
header is hello
aname is ????
lname is lastname

1
你可以尝试像这样。

String[] vals = "Hello??Man?HowAreYou????".split("\\?+");
System.out.println(vals[0]+vals[1]+vals[2]);

输出

HelloManHowAreYou

但是如果你想得到aname=?????,你可以将????? 五个问号替换为其他符号,并在分割后再替换回?????

String processed="Hello????Good? ? ....???".replace("????","*");

输出

Hello*Good? ? ....???

然后使用split函数分割字符“?”

你的替换仅在输入中有4个问号时才起作用。如果有更多或更少怎么办? - Absurd-Mind
@Absurd-Mind 是的,我同意!!!但在我开始编辑我的答案之前,我看到已经有一个答案了,这个答案是由“Bohemian”发布的。 - akash

0

这里是你正在寻找的代码。

使用Split和HashMap实现。

已测试并执行。

import java.util.HashMap;
import java.util.Map;


    public class Sample {

        public static void main(String[] args) {
            // TODO Auto-generated method stub


    //      String[] vals = "Hello??Man?HowAreYou????".split("\\?+");
    //      System.out.println(vals[0]+vals[1]+vals[2]);

            String query="name==p==?header=hello?aname=?????lname=lastname";
               String[] params = query.split("\\?");  
                Map<String, String> map = new HashMap<String, String>();  
                for (String param : params)  
                {  
                    String name = param.split("=")[0];  
                    String value = param.substring(name.length(),param.length());  
                    map.put(name, value);  
                    System.out.println(name);
                    if(name.equals("")){
                        value+="?";
                    }
                    System.out.println(value.replaceAll(" ", ""));
                }  

        }

    }

0

我猜你正在解析URL。正确的方法是对所有特殊字符进行编码,例如值或名称中的 ?&=

更好的解决方案:编码字符

String name = "=p==";
String aname = "aname=????";
String lname = "lastname";
String url = "name=" + URLEncoder.encode(name, "UTF-8") +
             "?aname=" + URLEncoder.encode(aname, "UTF-8") +
             "?lname=" + URLEncoder.encode(lname, "UTF-8");

接下来你会得到类似这样的东西:

name=&#61;p&#61;&#61;?aname=&#63;&#63;&#63;&#63;?lname=lastname

这个可以轻松地分割和解码。

其他解决方案:错误的输入解析:

如果你坚持,这也可以。你可以使用正则表达式:

Pattern pattern = Pattern.compile("(\\w+?)=(\\S+?\\?+)");
Matcher m = pattern.matcher(query + "?");
while (m.find()) {
    String key = m.group(1);
    String value = m.group(2);
    value = value.substring(0, value.length() - 1);
    System.out.println(key + " = " +value);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接