0

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

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 来执行此操作。

4

3 回答 3

2

replaceAll我找到了一个使用and的两行解决方案split

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

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

我还假设第一个关键字是一系列非空白字符(没有尾随逗号)\\S+(?<!,)\\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
于 2013-09-18T08:59:37.763 回答
0

我想出了:

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

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

于 2013-09-17T16:40:24.973 回答
0

好的,因为 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();
}));
于 2013-09-17T18:29:55.153 回答