regex Java正则表达式,用于通过位于双大括号外部的破折号拆分字符串

fumotvh3  于 2023-03-04  发布在  Java
关注(0)|答案(4)|浏览(102)

我有一些字符串,我想基于破折号分隔,但只有当破折号存在于双花括号之外,如下所示:
{{abc-def}}-123-收益-{{ghi}}应分解为{{abc-def}}、123、收益、{{ghi}}
abc-{{123-def}}-收益-{{ghi}}应分解为abc,{{123-def}},收益,{{ghi}}
我尝试使用正则表达式来做这件事,但不能得到它,因为我是新手与正则表达式。根据一些答案,我可以研究,我尝试了以下部分,但没有得到预期的输出:

String regex = "-(?!\\{\\{^\\{\\{\\}\\}*\\}\\})";
String newRegex = "-(?:[^,\"]|\"[^\"]*\")+-";
String abc = "{{abc-def}}-123-benefit-{{def}}";
String[] output1 = abc.split(regex);
String[] output2 = abc.split(newRegex);

输出1为

["{{abc", "def}}", "123", "benefit", "{{def}}"]

输出2为

["{{abc", "{{def}}"]

预期输出为

["{{abc-def}}", "123", "benefit", "{{def}}"]
iqxoj9l9

iqxoj9l91#

您可以匹配正则表达式

(?:\{\{.*?\}\}|[^{}\-]+)

Demo
该表达式可以分解如下。

(?:         begin a non-capture group
  \{\{      match literal
  .*?       match zero or more chars other than line terminators, lazily
  \}\}      match literal
|           or
  [^{}\-]+  match one or more characters other than '{', '}' or '-'
)           end non-capture group
aoyhnmkz

aoyhnmkz2#

这是一个没有答案的问题,但是你花了一个小时才得到一个正则表达式的答案,这花了我20分钟,包括一些简单的测试和评论,这比我想象的要复杂一些,尽管也许可以改进。
我添加了一些注解来说明我正在做的事情,向parse()方法添加一些Javadoc也会使它更具可读性。
如果你觉得有帮助,请随意复制。

package stackoverflow;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Brenden
 */
public class ParseDashBrace {
   
   public static void main( String[] args ) {
      List<String> test1 = parse( "{{abc-def}}-123-benefit-{{ghi}}" );
      System.out.println( "Test1 " + test1 );
      List<String> test2 = parse( "abc-{{123-def}}-benefit-{{ghi}}" );
      System.out.println( "Test2 " + test2 );
   }
   
   static List<String> parse( String line ) {
      ArrayList<String> tokens = new ArrayList<>();
      boolean inBrace = false;
      boolean firstBrace = false;
      int start = 0; 
      int end = 0;
      // parse the string, split on - and {{}}
      for( ; end < line.length(); end++ ) {
         char c = line.charAt( end );
         if( !inBrace ) {
            // if we are not inside braces, then we look for "-"
            if( c == '-' ) {
               if( start != end )
                  tokens.add( line.substring( start, end) );
               start = end+1;
            } else if( c == '{' ) {
               // we also need to know when we find a brace and are inside
               inBrace = true;
            }
         } else {
            if( c == '}' ) {
               if( firstBrace ) {
                  // we had a first brace and now we found another, two braces total
                  tokens.add( line.substring( start, end+1 ) );
                  start = end+1;
                  firstBrace = false;
                  inBrace = false;
               } else {
                  // this is just the first end brace, flag it, wait for next one
                  firstBrace = true;
               }
            }
         }
      }
      if( start != end ) 
         tokens.add( line.substring( start, end ) );
      return tokens;
   }
}
gudnpqoy

gudnpqoy3#

备选方案:
使用的正则表达式:

"(?<!\\{\\{\\w{1,100})-"

请参见下面上下文和测试台中的regex:

public static void main(String[] args) {
    String input1 = "{{abc-def}}-123-benefit-{{ghi}}";
    String input2 = "abc-{{123-def}}-benefit-{{ghi}}";

    String regex = "(?<!\\{\\{\\w{1,100})-";

    System.out.println("Result of input1: " + Arrays.asList(input1.split(regex)));
    System.out.println("Result of input2: " + Arrays.asList(input2.split(regex)));
}

输出:

Result of input1: [{{abc-def}}, 123, benefit, {{ghi}}]
Result of input2: [abc, {{123-def}}, benefit, {{ghi}}]

备注:

Used Pattern:
(?<!X)  X, via zero-width negative lookbehind

在此阅读更多关于模式的信息:https://docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html
用于测试正则表达式的其他工具:https://regex101.com/

jbose2ul

jbose2ul4#

如果你使用matcher而不是split,你的正则表达式会更简单。注意,在你的第一个正则表达式中,^作为输入锚的开始,所以永远不会匹配。
对于matcher,可以使用以下正则表达式:

\{\{.*?\}\}|[^-]+

代码:

import java.util.*;
import java.util.regex.*;

// ...

        String regex = "\\{\\{.*?\\}\\}|[^-]+";
        String abc = "{{abc-def}}-123-benefit-{{def}}";
        ArrayList<String> output = new ArrayList<>();
        Matcher m = Pattern.compile(regex).matcher(abc);
        while (m.find()) {
            output.add(m.group());
        }

相关问题