【问题标题】:Java - Help on using "split()"Java - 关于使用“split()”的帮助
【发布时间】:2015-04-23 13:15:44
【问题描述】:

我正在尝试在 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", "!"}` 

【问题讨论】:

  • 到目前为止你写了什么?
  • 所以你想同时拥有一个结果,即拆分结果+匹配模式?
  • 请努力而不是要求 SO 为您编写代码。
  • 请告诉我们预期的输出?
  • 值得一提的是,在其他语言中,您可以简单地使用 .split("([A-Za-z0-9]+)")(带有捕获组),但 Java 缺少此功能。

标签: java regex split


【解决方案1】:

正如其他海报所指出的,一种方法是使用您的模式,然后使用相反的模式。这可以通过一个正则表达式来完成,([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, !

【讨论】:

  • 您应该修改正则表达式以匹配大小写 "+++ABC---..." (+1)
【解决方案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) 一起使用以创建具有所需拆分结果的字符串数组。

【讨论】:

  • 这实际上是比使用倒置正则表达式的解决方案(包括我的)更好的解决方案。
【解决方案3】:

由于正则表达式组是有限的,我认为,唯一的方法是按 your_pattern 和 ANTY-your_pattern 拆分并逐个加入结果,如下所示:

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:不检查letess序列是否在输入字符串的第一个,所以如果需要,添加id。

【讨论】:

    【解决方案4】:

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

    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();
     }
    

    }

    类似的东西。抱歉代码不好,但我认为您可以理解。

    【讨论】:

      【解决方案5】:

      这里有循环版本:

        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;
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多