2013-09-17 3 views
0

Я ищу регулярное выражение, чтобы разделить следующие строкиRegex разбить строку на разные части (с помощью Java)

red 12478 
blue 25 12375 
blue 25, 12364 

Это должно дать

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

Каждая линия имеет 2-х частей, набор ключевых слов и набор идентификаторов. Ключевые слова разделяются пробелами, а идентификаторы разделяются запятыми.

я придумал следующее регулярное выражение: \s*((\S+\s+)+?)([\d\s,]+)

Однако она не на второй. Я пытался работать с опережающим просмотром, но не вполне могу работать его

Я пытаюсь разделить строку на составные части (ключевые слова и идентификаторы)

Форматом каждой строки является один или больше разделенных пробелами ключевых слов, за которыми следует один или несколько идентификаторов, разделенных запятыми. Идентификаторы являются только числовыми, а ключевые слова не содержат запятых.

Я использую Java для этого.

+4

Пожалуйста, точный язык вы используете. –

+0

Должен ли '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'после? – Broxzier

+0

Что должно сочетаться для разбиения строки? – Ashwani

ответ

2

Я нашел решение две строки с использованием replaceAll и split:

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

Я предположил, что запятая всегда будет сразу же после того, как идентификатор для каждого идентификатора (это может быть обеспечено путем удаления пространства соседнего в запятую) и что нет конечного пространства.

Я также предположил, что первое ключевое слово представляет собой последовательность символов без пробелов (без запятой) \\S+(?<!,)\\s+, а остальные ключевые слова (если есть) - это цифры (\\d+\\s+)*. Я сделал это предположение на основе вашей попытки регулярного выражения.

Regex здесь очень просто, просто возьмите (с жадностью) любую последовательность допустимых ключевых слов, за которой следует пробел (или пробелы). Самый длинный будет список ключевых слов, остальные будут идентификаторами.

Полный код:

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 
0

я придумал:

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

, как показано на http://rubular.com/r/y52XVeHcxY, который, кажется, чтобы пройти тесты. Вкладывать ключевые слова между подстроками соответствия - это простой вопрос.

0

Ok, так как OP не указать целевой язык, я готов наклона на этой мельнице за обед, как дразнилка мозга и обеспечиваю C#/Net Regex заменить матч оценщик, который дает требуемую мощность.:

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

Примечания нет проверки ошибок, и это прекрасный пример использования выражения LAMDA для оценщика матча и возвращая заменить на правила делает работу. Также следует отметить, что из-за небольшого размера выборки данных он не обрабатывает несколько идентификаторов/ключевых слов, как может быть на самом деле.

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(); 
})); 
Смежные вопросы