String.split()不作用于分号或空格分隔符

时间:2012-01-28 02:19:59

标签: java android

这可能是一个简单的问题,但我已经谷歌搜索超过一个小时,还没有找到答案。

我正在尝试使用String.split()方法和一个小型Android应用程序来分割输入字符串。输入字符串将是:“启动ip:192.168.1.101;端口:5900”。我在两次迭代中这样做,以确保所有必需的参数都存在。我首先尝试对空格和分号进行拆分,以便对单个标记进行整理。接下来,我试图拆分冒号,以剥去每条信息的识别标签。

因此,例如,我希望第一轮拆分能够从上面的示例字符串中获取以下数据: (1)发射 (2)ip:192.168.1.101 (3)港口:5900

然后第二轮会给我以下内容: (1)192.168.1.101 (2)5900

但是,我写的以下代码并没有给出我的期望:

private String[] splitString(String inputString)
{
    String[] parsedString;
    String[] orderedString = new String[SOSLauncherConstants.SOCKET_INPUT_STRING_PARSE_VALUE];

    parsedString = inputString.trim().split("; ");

    Log.i("info", "The parsed data is as follows for the initially parsed string of size " + parsedString.length + ": ");
    for (int i = 0; i < parsedString.length; ++i)
    {
        Log.i("info", parsedString[i]);
    }

    for (int i = 0; i < parsedString.length; ++i )
    {
        if (parsedString[i].toLowerCase().contains(SOSLauncherConstants.PARSED_LAUNCH_COMMAND_VALUE))
        {
            orderedString[SOSLauncherConstants.PARSED_COMMAND_WORD] = parsedString[i];
        }

        if (parsedString[i].toLowerCase().contains("ip"))
        {
            orderedString[SOSLauncherConstants.PARSED_IP_VALUE] = parsedString[i].split(":")[1];
        }
        else if (parsedString[i].toLowerCase().contains("port"))
        {
            orderedString[SOSLauncherConstants.PARSED_PORT_VALUE] = parsedString[i].split(":")[1];
        }
        else if (parsedString[i].toLowerCase().contains("username"))
        {
            orderedString[SOSLauncherConstants.PARSED_USERNAME_VALUE] = parsedString[i].split(":")[1];
        }
        else if (parsedString[i].toLowerCase().contains("password"))
        {
            orderedString[SOSLauncherConstants.PARSED_PASSWORD_VALUE] = parsedString[i].split(":")[1];
        }
        else if (parsedString[i].toLowerCase().contains("color"))
        {
            orderedString[SOSLauncherConstants.PARSED_COLOR_VALUE] = parsedString[i].split(":")[1];
        }
    }

    Log.i("info", "The parsed data is as follows for the second parsed string of size " + orderedString.length + ": ");
    for (int i = 0; i < orderedString.length; ++i)
    {
        Log.i("info", orderedString[i]);
    }

    return orderedString;
}

结果,我得到以下内容: 对于大小为1的解析字符串,解析后的数据如下:

启动ip:192.168.1.106;端口:5900

对于大小为6的第二个解析字符串,解析后的数据如下:

启动ip:192.168.1.106;端口:5900

192.168.1.106;端口

然后,当然,它会崩溃,因为for循环会遇到一个空字符串。

旁注: 以下代码段来自定义所有字符串索引的常量类 -

public static final int SOCKET_INPUT_STRING_PARSE_VALUE = 6;
public static final int PARSED_COMMAND_WORD = 0;
public static final String PARSED_LAUNCH_COMMAND_VALUE = "launch";
public static final int PARSED_IP_VALUE = 1;
public static final int PARSED_PORT_VALUE = 2;
public static final int PARSED_USERNAME_VALUE = 3;
public static final int PARSED_PASSWORD_VALUE = 4;
public static final int PARSED_COLOR_VALUE = 5;

我调查需要一个可能的转义(通过在分号前插入\\)分号分隔符,甚至尝试使用它,但这不起作用。奇怪的是,空格和分号都不能作为分隔符,但冒号第二次起作用。有没有人会有什么想法会导致这个?

谢谢你的时间!

编辑:我还应该补充一点,我通过WiFi套接字连接收到了字符串。我认为这不应该有所作为,但我希望你能获得所需的所有信息。

3 个答案:

答案 0 :(得分:9)

String.split(String)采用正则表达式。使用"[; ]"。例如:

"foo;bar baz".split("[; ]")

将返回包含"foo""bar""baz"的数组。

如果您需要空格组作为单个分隔符,您可以使用以下内容:

"foo;bar     baz".split("(;| +)")

答案 1 :(得分:1)

我相信String.split()会尝试在您指定的每个字符上(或在正则表达式上)拆分,而不是分别对每个字符进行拆分。也就是说,split(";.")根本不会拆分"a;b.c",而是会拆分"a;.b"

Guava's Splitter可能会有更好的运气,这意味着比java.lang.String.split稍微不可预测。

我会写类似

的内容
 Iterable<String> splits = Splitter.on(CharMatcher.anyOf("; ")).split(string);

Splitter还提供流畅式自定义,例如“修剪结果”或“跳过空字符串。”

答案 2 :(得分:0)

你有没有理由使用String.split(),但没有使用正则表达式?如果字符串格式一致,这是正则表达式的完美候选者。

我不确定你的格式是否已修复,如果是,那么下面的正则表达式应该为你分解(确定有人可以提出一个更优雅的正则表达式)。如果你有几个命令字符串,那么你可以使用更灵活的正则表达式并循环遍历所有组:

Pattern p = Pattern.compile("([\w]*)[ ;](([\w]*):([^ ;]*))*");
Matcher m = p.match( <input string>);
if( m.find() )
  command = m.group(1);
  do{
    id = m.group(3);
    value = m.group(4);
} while( m.find() );

在线测试正则表达式的好地方是http://www.regexplanet.com/simple/index.html。如果你只想让正则表达式正确,它允许你使用正则表达式而无需每次都编译和启动应用程序。