java正则表达式拆分字符串

标签 java regex string split

我有点卡住了,试图想出正则表达式来分解具有以下属性的字符串:

  1. 由 | 分隔(管道)字符
  2. 如果单个值包含管道,则使用\(反斜杠)转义
  3. 如果单个值以反斜杠结尾,则用反斜杠转义

例如,这里有一些我想分解的字符串:

  1. One|Two|Three 应该产生:["One", "Two", "Three"]
  2. One\|Two\|Three 应该产生:["One|Two|Three"]
  3. One\\|Two\|Three 应该产生:["One\", "Two|Three"]

现在我怎么能用一个正则表达式把它分开呢?

更新:正如你们中的许多人所建议的,这不是正则表达式的良好应用。此外,正则表达式解决方案比仅遍历字符慢几个数量级。我最终遍历了字符:

public static List<String> splitValues(String val) {
    final List<String> list = new ArrayList<String>();
    boolean esc = false;
    final StringBuilder sb = new StringBuilder(1024);
    final CharacterIterator it = new StringCharacterIterator(val);
    for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
        if(esc) {
            sb.append(c);
            esc = false;
        } else if(c == '\\') {
            esc = true;
        } else if(c == '|') {
            list.add(sb.toString());
            sb.delete(0, sb.length());
        } else {
            sb.append(c);
        }
    }
    if(sb.length() > 0) {
        list.add(sb.toString());
    }
    return list;
}

最佳答案

技巧是不要使用 split() 方法。这迫使您使用后视来检测转义字符,但是当转义本身被转义时(正如您所发现的那样),它会失败。您需要使用 find() 来匹配 tokens 而不是分隔符:

public static List<String> splitIt(String source)
{
  Pattern p = Pattern.compile("(?:[^|\\\\]|\\\\.)+");
  Matcher m = p.matcher(source);
  List<String> result = new ArrayList<String>();
  while (m.find())
  {
    result.add(m.group().replaceAll("\\\\(.)", "$1"));
  }
  return result;
}

public static void main(String[] args) throws Exception
{
  String[] test = { "One|Two|Three", 
                    "One\\|Two\\|Three", 
                    "One\\\\|Two\\|Three", 
                    "One\\\\\\|Two" };
  for (String s :test)
  {
    System.out.printf("%n%s%n%s%n", s, splitIt(s));
  }
}

输出:

One|Two|Three
[One, Two, Three]

One\|Two\|Three
[One|Two|Three]

One\\|Two\|Three
[One\, Two|Three]

One\\\|Two
[One\|Two]

关于java正则表达式拆分字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6879610/

相关文章:

java - C++中的DWORD数据类型及其在Java中的转换

java - 无论 Java 中的计时器如何,Tomcat 的重新启动都会使作业每次都运行

java - 与 jar 文件相比,为什么 js 框架的大小如此之小?

javascript - 我可以将 RegExp 和 Function 存储在 JSON 中吗?

c++ - 是否必须释放 std::string.c_str() 或 std::string.data() 返回的指针?

Android:android.content.res.Resources$NotFoundException:字符串资源 ID #0x5

java - 在使用 Keycloak 保护的网络应用程序中获取登录用户名

javascript - Google Apps 脚本 - 将 gmail 中的数据提取到电子表格中

c++ - std::vector<string> 奇怪的行为

javascript - 无法将此主题与 preg_match 匹配