2011-11-25 69 views
43

我试图制定出如下像这样的模式在Java分裂的字符串的方法:如何在字母和数字之间(或数字和字母之间)分割字符串?

String a = "123abc345def"; 

的从这个结果应该是以下几点:

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

不过我我完全无法理解我如何实现这一目标。请有人帮助我吗?我尝试过在网上搜索类似的问题,但是在搜索中正确地使用它是非常困难的。

请注意: &数字可能会有所不同的字母数字(例如有可能是像这样“1234a5bcdef”字符串)

+0

我还没有尝试任何事情 - 我甚至不知道在哪里的问题开始,因为它是第一个我曾经遇到过类似的东西。 –

+0

要求用户为所有关于作业问题的问题添加“作业”标签。 – Michael

+0

@迈克尔这不是一个'家庭作业'的问题。我以前从未遇到过这样的问题。 –

回答

74

你可以尝试拆就(?<=\D)(?=\d)|(?<=\d)(?=\D),如:

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

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

+3

请记住,该解决方案会将字符(既不是数字也不是字母)威胁为字母,因此您可能需要验证您的零件。 – Mario

+0

@Romain,它的确如此:http://ideone.com/XDsKn – Qtax

+0

@TimPietzcker我不是一个投票的这个问题 - 我从来没有见过这个在Java中使用,并坦率地要求确认它在Java中的作用。现在我甚至都在鼓吹这个。 – Romain

3

使用两种不同的模式:[0-9]*[a-zA-Z]*,并由它们中的每一个分开两次。

+0

感谢您的帮助。我不确定我完全理解你的意思。请你能详细解释一下,或者提供一个基本的例子,这样我就能明白你的意思了吗? –

+0

从语义上讲,它会是'[0-9] +'和'[a-zA-Z] +'......尽管他们也会这样做。 – Romain

+0

首先,将字符串分割为数字模式并获取字符串数组,然后在字符模式中分割字符串并获取数组数组。连接两个数组,你将得到你想要的结果 – mishadoff

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 
} 
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; 
} 
+0

谢谢..其实我的要求.. :) –

8

你可以试试这个:

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"] 
+0

这是无效的Java语法。 –

+0

感谢Christoffer,我编辑过。 –

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阵列。

+0

我喜欢你的代码,一个评论:return c> ='0'&& c <='9'更好。 –

+0

@ LaurensOp'tZandt - 编辑好。 – sergeyan

1

我在为关键任务代码做这类事情。就像每一秒钟的一小部分,因为我需要在不可察觉的时间内处理18万个条目。所以我跳过了正则表达式并完全拆分,并允许对每个元素进行内联处理(尽管将它们添加到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)); 
} 
相关问题