Java - 有关使用“split()”的帮助

时间:2015-04-23 13:15:45

标签: java regex split

我试图在java中编写一个类似于Java中的“split()”命令的代码,但是不会删除与正则表达式匹配的部分。例如:

String str = "ABC---DEF***GHI///JKL#@!"; 

然后

`str.split("[A-Za-z0-9]+")` returns `{"---", "***", "///", "#@!"}`. 

但是,我想写一个类似于split()的方法,它将字符串AT匹配正则表达式而不是AROUND它。

`An example of an implementaion would be: 
public static String[] splitString(String input, String regex)` 

因此:

`splitString("ABC---123DEF***456GHI///JKL9#@6!", "[A-Za-z0-9]+")` 

会给:

`{"ABC", "---", "123DEF", "***", "456GHI", "///", "JKL9", "#@", "6", "!"}` 

5 个答案:

答案 0 :(得分:2)

使用匹配器查找正则表达式的所有匹配项,然后自己构建拆分结果。

以下方法显示正则表达式的所有匹配项的位置:

public static void findMatches(String input, String regex)
{
    Matcher matcher = Pattern.compile(regex).matcher(input);

    while (matcher.find()) {
        System.out.printf("%d-%d%n", matcher.start(), matcher.end());
    }
}

现在使用您以这种方式找到的索引和String.substring(beginIndex, endIndex)一起创建具有所需拆分结果的字符串数组。

答案 1 :(得分:2)

正如其他海报所指出的,一种方法是使用你的模式,然后反过来。这可以使用单个正则表达式([A-Za-z0-9]*)([^A-Za-z0-9]*)

来完成
String str = "ABC---DEF***GHI///JKL#@!";
Matcher m = Pattern.compile("([A-Za-z0-9]*)([^A-Za-z0-9]*)").matcher(str);
List<String> result = new ArrayList<>();
while(m.find()) {
    for(int i=1; i<=m.groupCount(); i++) {
        if(!m.group(i).isEmpty()) {
            result.add(m.group(i));
        }
    }
}
System.out.println(StringUtils.join(result, ", "));

输出:

ABC, ---, 123DEF, ***, 456GHI, ///, JKL9, #@, 6, !

答案 2 :(得分:1)

由于正则表达式组是有限的,我认为,唯一的方法是通过your_pattern和ANTY-your_pattern进行拆分,并将结果1加1,如下所示:

ANTY-regex对你来说是[^A-Za-z0-9]+。 (^在[]否定int的开头^)

public String[] splitString(String input, String regex, String antiRegex)
{
    String[] letters = input.split(regex);
    String[] symbols = input.split(antiRegex);
    String[] result = new String[letters.length + symbols.length];
    for (int i = 0; i < letters.length; i++)
    {
        result[i] = letters[i];
        if (++i < symbols.length) //important: ++i, NOT i++
        {
            result[i] = symbols[i];
        }
    }
    return result;
}

UPD:没有检查输入字符串中是否有lettess序列,所以如果需要,请添加id。

答案 3 :(得分:1)

您可以使用正则表达式编写一个方法来执行此操作,并从原始字符串中删除第一个找到的匹配项。我有点懒于编写整个代码,但在伪代码中它将是类似的东西。您将使用两种模式 - 一种用于单词,另一种用于字符串开头的所有其他模式:

Pattern literals="(^[A-Za-z0-9]+)";
Pattern everythingElse="(^[^A-Za-z0-9]+)";
List<String> results;

while(str is not finished){
 Matcher literalsMatcher= literals.matcher(str);
 if(literalsMatcher.find()){
   results.add(literalsMatcher.group(1));
   str.subString(0,literalsMatcher.group(1).length();
 }

Matcher everythingElseMatcher = everythingElse.matcher(str);
 if(everythingElseMatcher.find()){
   results.add(everythingElseMatcher.group(1));
   str.subString(0,everythingElseMatcher.group(1).length();
 }

}

这样的事情。对不起的代码感到抱歉,但我认为你可以得到这个想法。

答案 4 :(得分:0)

这里有经常性版本:

  public static String[] split(String msg, String expr){
      if (msg.split(expr).length == 1){
        return msg.split(expr);
      }
      String[] tab = msg.split(expr, 2);
      String exprStr = msg.substring(tab[0].length(),  msg.length() -  tab[1].length());
      int exprLength = msg.length() - tab[0].length() - tab[1].length();
      String[] tab1 = split(msg.substring(tab[0].length() + exprLength, msg.length()), expr);
      String[] result = new String[1 + 1 + tab1.length];
      result[0] = tab[0];
      result[1] = exprStr;
      for (int i = 0; i <  tab1.length;++i){
         result[i + 2] = tab1[i];
      }
      return result;

}