我正在寻找一个正则表达式来分割以下字符串
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来做这件事。
答案 0 :(得分:2)
我找到了使用replaceAll
和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();
}
}
示例运行:
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();
}));