正则表达式将字符串拆分为不同的部分(使用Java)

时间:2013-09-17 16:24:23

标签: java regex

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

red 12478
blue 25 12375
blue 25, 12364

这应该给出

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

每一行有两部分,一组关键字和一组ID。关键字用空格分隔,ID用逗号分隔。

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

然而,第二个失败了。我一直在尝试使用前瞻,但不能完全解决这个问题

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

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

我正在使用Java来做这件事。

3 个答案:

答案 0 :(得分:2)

我找到了使用replaceAllsplit的双线解决方案:

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();
    }
}

示例运行:

red 124
Keywords:
    red
IDs:
    124

red 25 124
Keywords:
    red
    25
IDs:
    124

red 25, 124
Keywords:
    red
IDs:
    25
    124

答案 1 :(得分:0)

我想出了:

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

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

答案 2 :(得分:0)

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

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();
}));