【问题标题】:Regex to split a string into different parts (using Java)正则表达式将字符串拆分为不同的部分(使用 Java)
【发布时间】:2013-09-17 16:24:23
【问题描述】:

我正在寻找一个正则表达式来拆分以下字符串

red 12478
blue 25 12375
blue 25, 12364

这应该给

Keywords red, ID 12478
Keywords blue 25, ID 12475
Keywords blue IDs 25, 12364

每行有 2 个部分,一组关键字和一组 ID。关键字以空格分隔,ID 以逗号分隔。

我想出了以下正则表达式:\s*((\S+\s+)+?)([\d\s,]+)

但是,第二个失败了。我一直在尝试使用前瞻,但无法完全解决

我正在尝试将字符串拆分为其组成部分(关键字和 ID)

每一行的格式是一个或多个空格分隔的关键字,后跟一个或多个逗号分隔的 ID。 ID 仅为数字,关键字不包含逗号。

我正在使用 Java 来执行此操作。

【问题讨论】:

  • 请准确说明您使用的语言。
  • ,red 之后是否必须存在,但不是在blue 之后?
  • 分割字符串应该匹配什么?
  • 看起来更像是匹配和替换而不是拆分 imo。
  • 已更新。抱歉,输出中缺少逗号

标签: java regex


【解决方案1】:

我找到了使用replaceAllsplit 的两行解决方案:

pattern = "(\\S+(?<!,)\\s+(\\d+\\s+)*)";
String[] keywords = theString.replaceAll(pattern+".*","$1").split(" ");
String[] ids = theString.split(pattern)[1].split(",\\s?");

我假设逗号总是紧跟在每个 ID 的 ID 之后(这可以通过删除与逗号相邻的空格来强制执行),并且没有尾随空格。

我还假设第一个关键字是非空白字符序列(不带尾随逗号)\\S+(?&lt;!,)\\s+,其余关键字(如果有)是数字(\\d+\\s+)*。我根据您的正则表达式尝试做出了这个假设。

这里的正则表达式非常简单,只需(贪婪地)采用任何后跟空格(或空格)的有效关键字序列。最长的是关键字列表,其余的是 ID。

完整代码:

public static void main(String[] args){
    String pattern = "(\\S+(?<!,)\\s+(\\d+\\s+)*)";
    Scanner sc = new Scanner(System.in);
    while(true){
        String theString = sc.nextLine();

        String[] keywords = theString.replaceAll(pattern+".*","$1").split(" ");
        String[] ids = theString.split(pattern)[1].split(",\\s?");

        System.out.println("Keywords:");
        for(String keyword: keywords){
            System.out.println("\t"+keyword);
        }
        System.out.println("IDs:");
        for(String id: ids){
            System.out.println("\t"+id);
        }
        System.out.println();
    }
}

示例运行:

红124 关键词: 红色的 标识: 124 红色 25 124 关键词: 红色的 25 标识: 124 红色 25, 124 关键词: 红色的 标识: 25 124

【讨论】:

    【解决方案2】:

    我想出了:

    (red|blue)( \d+(?!$)(?:, \d+)*)?( \d+)?$
    

    http://rubular.com/r/y52XVeHcxY 中所示,它似乎通过了您的测试。在匹配子字符串之间插入关键字是一件简单的事情。

    【讨论】:

      【解决方案3】:

      好的,因为 OP 没有指定目标语言,我愿意在午餐时在这个风车上倾斜作为脑筋急转弯,并提供 C#/.Net 正则表达式替换匹配评估器,它给出所需的输出:

      Keywords red, ID 12478
      Keywords blue 25 ID 12375
      Keywords blue IDs 25, 12364
      

      请注意,没有错误检查,这是使用 lamda 表达式作为匹配评估器并根据规则返回替换的好例子。另外值得注意的是,由于数据的采样量很小,它不能处理实际情况下的多个 ID/关键字。

      string data = @"red 12478
      blue 25 12375
      blue 25, 12364";
      
      var pattern = @"(?xmn)   # x=IgnorePatternWhiteSpace m=multiline n=explicit capture
      ^
      (?<Keyword>[^\s]+)       # Match Keyword Color
      [\s,]+
      (
        (?<Numbers>\d+)       
        (?<HasComma>,)?       # If there is a comma that signifies IDs
        [,\s]*
      )+                      # 1 or more values
      $";
      
      
      Console.WriteLine (Regex.Replace(data, pattern, (mtch) =>
      {
          StringBuilder sb = new StringBuilder();
      
          sb.AppendFormat("Keywords {0}", mtch.Groups["Keyword"].Value);
      
          var values = mtch.Groups["Numbers"]
                           .Captures
                           .OfType<Capture>()
                           .Select (cp => cp.Value)
                           .ToList();
      
          if (mtch.Groups["HasComma"].Success)
          {
              sb.AppendFormat(" IDs {0}", string.Join(", ", values));
          }
          else
          {
              if (values.Count() > 1)
                  sb.AppendFormat(" {0} ID {1}", values[0], values[1]  );
              else
                  sb.AppendFormat(", ID {0}", values[0]);
          }
      
          return sb.ToString();
      }));
      

      【讨论】:

        猜你喜欢
        • 2012-12-07
        • 1970-01-01
        • 2019-05-14
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        • 2011-10-16
        • 1970-01-01
        相关资源
        最近更新 更多