【问题标题】:how to split a string by "|"如何用“|”分割字符串
【发布时间】:2014-05-12 12:56:48
【问题描述】:

我想用正则表达式来分割这个字符串:

String filter = "(go|add)addition|(sub)subtraction|(mul|into)multiplication|adding(add|go)values|(add|go)(go)(into)multiplication|";

我想用| 分割它,除非管道出现在括号内,在这种情况下它们应该被忽略,即我排除了这样的输出:

(go|add)addition
(sub)subtraction
(mul|into)multiplication
adding(add|go)values
(add|go)(go)(into)multiplication

更新

然后我想将括号内的单词从开头移到结尾。

像这样..

addition(go|add)
subtraction(sub)
multiplication(mul|into)
adding(add|go)values
multiplication(add|go)(go)(into)

我已经尝试过这个正则表达式:Splitting of string for `whitespace` & `and`,但他们使用了引号,我无法使其适用于括号。

【问题讨论】:

  • 如果您想对这个操作使用单个正则表达式,那么您需要非常熟悉前瞻和后瞻语法(?...)
  • @DerGolem 查看我发布的link..他们使用了'并且我想使用()..
  • @DerGolem 这不是真的。前瞻/后视是可能的
  • 括号总是在开头吗?他们总是在那里吗?
  • 我最好使用一个唯一的分隔符,如"(go|add)addition;(sub)subtraction;(mul|into)multiplication"(注意最后一个分隔符没用)。这里的分隔符是 ;

标签: java android regex


【解决方案1】:

15 分钟前已看到此问题。既然问得正确,这是我的回答建议:

尝试使用正则表达式很复杂,因为您需要计算括号。我建议您像这样手动解析字符串:

public static void main(String[] args) {

  String filter = "(go|add)addition|(sub)subtraction|(mul|into)multiplication|";

  List<String> strings = new LinkedList<>();
  int countParenthesis = 0;
  StringBuilder current = new StringBuilder();

  for(char c : filter.toCharArray()) {
    if(c == '(') {countParenthesis ++;}
    if(c == ')') {countParenthesis --;}
    if(c == '|' && countParenthesis == 0) {
      strings.add(current.toString());
      current = new StringBuilder();
    } else {
      current.append(c);
    }
  }
  strings.add(current.toString());

  for (String string : strings) {
    System.out.println(string+" ");
  }

}

输出:

(go|add)addition 
(sub)subtraction 
(mul|into)multiplication 

【讨论】:

    【解决方案2】:

    如果你没有有嵌套括号(所以没有(mul(iple|y)|foo))你可以使用:

    ((?:\([^)]*\))*)([^()|]+(?:\([^)]*\)[^()|]*)*)
    
    (                          #start first capturing group
        (?:                    # non capturing group
             \([^)]*\)         # opening bracket, then anything except closing bracket, closing bracket
        )*                     # possibly multiple bracket groups at the beginning
    )
    (                          # start second capturing group
        [^()|]+                # go to the next bracket group, or the closing |
        (?:
            \([^)]*\)[^()|]*   # bracket group, then go to the next bracket group/closing |
         )*                    # possibly multiple brackets groups
    )                          # close second capturing group
    

    并替换为

    \2\1
    

    说明

    • ((?:\([^)]*\))*) 匹配并捕获开头的所有括号组
    • [^()|]*()| 之外的任何内容。如果没有任何括号,这将匹配所有内容。
    • (?:\([^)]*\)[^()|]*)(?:...) 是一个非捕获组,\([^)]*\) 匹配括号内的所有内容,[^()|]* 将我们带到下一个括号组或结束匹配的 |

    代码示例:

    String testString = "(go|add)addition|(sub)subtraction|(mul|into)multiplication|adding(add|go)values|(add|go)(go)(into)multiplication|";
    Pattern p = Pattern.compile("((?:\\([^)]*\\))*)([^()|]+(?:\\([^)]*\\)[^()|]*)*)");
    Matcher m = p.matcher(testString);
    while (m.find()) {
        System.out.println(m.group(2)+m.group(1));
    }
    

    输出 (demo):

    addition(go|add)
    subtraction(sub)
    multiplication(mul|into)
    adding(add|go)values
    multiplication(add|go)(go)(into)
    

    【讨论】:

    • 没有参数是可选的,它们可以在任何地方像这样 String filter = "(go|add)addition|(sub)subtraction|(mul|into)multiplication|multiplication|multipl(mul |进入)化|";
    • 是的,我明白了,你能再帮我一个忙吗,在字符串的末尾添加括号,例如 add(go|add) pls...
    • @Prakash:1。我在另一条评论中看到您可以拥有(foo|bar(foobar))?这些是嵌套结构,更难做到。我目前的答案不会抓住他们。 2。你想要所有的括号到最后吗? multiplication(foo)bar(foobar) 会发生什么?
    • @Prakash 关于 SO 的好问题的关键是在您的问题中提供 all 相关信息。到目前为止,您收到的任何答案都没有解决您的问题,因为您没有提供足够的细节(特别是 (..|..) 可能在任何地方,而不仅仅是在开头,而且可能有嵌套的括号)。
    • @Prakash:请编辑您的问题以添加所有您的要求。
    【解决方案3】:

    你的字符串

    "(go|add)加法|(sub)减法|(mul|into)乘法|"

    有一个模式 |( 您可以从中拆分此特定的字符串模式。但是如果您的子字符串在 ex 之间包含括号(“(”)),这不会给出预期的结果:

    (go|(add))addition....继续

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      设置 bool 以跟踪您是否在括号内。

      布尔 isInside = True;

      loop through string
      if char at i = ")" isInside = False
      if isInside = false
      code for skipping |
      else
      code for leaving | here
      

      我认为这样的东西应该可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-12
        • 2011-03-26
        • 1970-01-01
        • 2017-11-30
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多