仅针对非转义字符的正则表达式分割

时间:2018-01-11 15:54:38

标签: java regex split

我有一个字符串,我需要拆分某些字符,但如果它们被转义则不能。到目前为止,我使用了正则表达式,但意识到如果转义字符本身被转义,我会遇到麻烦。所以如果:是分裂字符和?我期待这种行为的逃避字符

a:b?:c??:d???:e????:f

变为

a
b?:c??
d???:e????
f

底线:

    只有在以下情况下才会发生
  • 拆分:还是没有?
  • 全部?必须保留。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

代码

See regex in use here

(?<!\?)(?:\?{2})*\K:

其他变体:

(?:^|[^?])(?:\?{2})*\K:       Doesn't use lookbehind
(?<=(?:^|[^?])(?:\?{2})*):    Doesn't use \K, uses variable length lookbehind

解释

  • (?<!\?)否定的背后隐藏确保之前的内容不匹配?
  • (?:\?{2})*多次匹配??
  • \K重置模式的起点。最终匹配中不再包含任何以前消费的字符
  • :按字面意思匹配

修改

在我的回答中的评论中,OP提到使用的语言是。由于Java不支持\K或可变宽度的外观,我决定使用正则表达式(以及Matcher对象的end()方法)与{ {3}}方法。

代码

substring()

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Ideone
{

    private static List<Integer> indices = new ArrayList<Integer>();
    private static List<String> result = new ArrayList<String>();

    public static void main (String[] args) throws java.lang.Exception
    {

        String str = "a:b?:c??:d???:e????:f";

        Pattern pattern = Pattern.compile("(?<!\\?)(?:\\?{2})*:");
        Matcher matcher = pattern.matcher(str);

        while(matcher.find()) {
            result.add(str.substring(getLastIndex(), matcher.end() - 1));
            indices.add(matcher.end());
        }
        result.add(str.substring(getLastIndex()));
        System.out.print(result);
    }

    private static int getLastIndex() {
        if(indices.isEmpty()) {
            return 0;
        } else {
            return indices.get(indices.size() - 1);
        }
    }
}

解释

  1. 循环匹配正则表达式模式(?<!\?)(?:\?{2})*:
  2. 从{1}}获取上一个索引(或0,如果它不存在)的子字符串,并将其添加到Matcher.end()列表。
  3. result(对于当前匹配)添加到Matcher.end()列表。
  4. 完成上述循环后,将indices列表中最后获得的索引的子字符串获取到字符串的末尾,并将其添加到indices列表中。

答案 1 :(得分:0)

没有lookbehind或\ K你可以使用类似下面的内容,但它会将匹配的非':'部分保存在一个组中:

example