如何在字母和数字之间(或数字和字母之间)拆分字符串?

时间:2011-11-25 14:53:19

标签: java regex string

我正试图找出一种在java中拆分字符串的方法,该方法遵循如下模式:

String a = "123abc345def";

此结果应如下:

x[0] = "123";
x[1] = "abc";
x[2] = "345";
x[3] = "def";

然而,我完全难以理解如何实现这一目标。请有人帮帮我吗?我尝试在网上搜索类似的问题,但是在搜索中正确地说出它是非常困难的。

请注意:字母数量&数字可能会有所不同(例如,可能有一个像'1234a5bcdef'这样的字符串)

8 个答案:

答案 0 :(得分:85)

您可以尝试拆分(?<=\D)(?=\d)|(?<=\d)(?=\D),例如:

str.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");

它匹配数字和非数字之间的位置(按任意顺序)。

  • (?<=\D)(?=\d) - 匹配非数字(\D)和数字(\d)之间的位置
  • (?<=\d)(?=\D) - 匹配数字和非数字之间的位置。

答案 1 :(得分:9)

怎么样:

private List<String> Parse(String str) {
    List<String> output = new ArrayList<String>();
    Matcher match = Pattern.compile("[0-9]+|[a-z]+|[A-Z]+").matcher(str);
    while (match.find()) {
        output.add(match.group());
    }
    return output;
}

答案 2 :(得分:7)

你可以试试这个:

Pattern p = Pattern.compile("[a-z]+|\\d+");
Matcher m = p.matcher("123abc345def");
ArrayList<String> allMatches = new ArrayList<>();
while (m.find()) {
    allMatches.add(m.group());
}

结果(allMatches)将是:

["123", "abc", "345", "def"]

答案 3 :(得分:3)

使用两种不同的模式:[0-9]*[a-zA-Z]*,并按每种模式拆分两次。

答案 4 :(得分:2)

如果您正在寻找不使用Java String功能的解决方案(例如splitmatch等),那么以下内容应该有所帮助:

List<String> splitString(String string) {
        List<String> list = new ArrayList<String>();
        String token = "";
        char curr;
        for (int e = 0; e < string.length() + 1; e++) {
            if (e == 0)
                curr = string.charAt(0);
            else {
                curr = string.charAt(--e);
            }

            if (isNumber(curr)) {
                while (e < string.length() && isNumber(string.charAt(e))) {
                    token += string.charAt(e++);
                }
                list.add(token);
                token = "";
            } else {
                while (e < string.length() && !isNumber(string.charAt(e))) {
                    token += string.charAt(e++);
                }
                list.add(token);
                token = "";
            }

        }

        return list;
    }

boolean isNumber(char c) {
        return c >= '0' && c <= '9';
    }

此解决方案将拆分数字和“单词”,其中“单词”是不包含数字的字符串。但是,如果您只想要包含英文字母的“单词”,则可以根据您的要求添加更多条件(如isNumber方法调用),轻松修改它(例如,您可能希望跳过包含非英文字母的单词)英文字母)。另请注意,splitString方法返回ArrayList,稍后可将其转换为String数组。

答案 5 :(得分:1)

多年没有使用Java,所以只是一些伪代码,这应该有助于你开始(对我来说比查找所有内容更快:)。

 string a = "123abc345def";
 string[] result;
 while(a.Length > 0)
 {
      string part;
      if((part = a.Match(/\d+/)).Length) // match digits
           ;
      else if((part = a.Match(/\a+/)).Length) // match letters
           ;
      else
           break; // something invalid - neither digit nor letter
      result.append(part);
      a = a.SubStr(part.Length - 1); // remove the part we've found
 }

答案 6 :(得分:1)

我正在为关键任务代码做这类事情。就像每秒钟的一小部分一样,因为我需要在不明显的时间内处理180k条目。所以我跳过正则表达式并完全拆分并允许对每个元素进行内联处理(尽管将它们添加到ArrayList<String>就可以了)。如果你想做这个确切的事情,但需要它快20倍......

void parseGroups(String text) {
    int last = 0;
    int state = 0;
    for (int i = 0, s = text.length(); i < s; i++) {
        switch (text.charAt(i)) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                if (state == 2) {
                    processElement(text.substring(last, i));
                    last = i;
                }
                state = 1;
                break;
            default:
                if (state == 1) {
                    processElement(text.substring(last, i));
                    last = i;
                }
                state = 2;
                break;
        }
    }
    processElement(text.substring(last));
}

答案 7 :(得分:0)

这不是吗 "d+|D+" 做这项工作,而不是麻烦: "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"