Regex - поймать неизвестное количество слов между - PullRequest
0 голосов
/ 05 января 2019

У меня есть следующие строки

  • 2011 Триест МЕД чистый / сырой / сырой
  • 2013 Триест фо / сырой / сырой
  • 2013 Ningbo East Pacific cca / cf / ce
  • 2014 Agioi theodoroi MED cde / fo / ce

Что я на самом деле хочу сделать, так это попытаться поймать Trieste MED (первая строка), Trieste (вторая строка), Ningbo east pacific (третья строка) и agioi theodoroi med (четвертая строка) как одну группу, называемую открытым портом. Обычно между датой 2013 года, например, сырой / сырой / сырой, есть от 1 до 4 слов.

Это то, что я пробовал до сих пор https://regex101.com/r/mYevqd/1.

Но это может привести к ошибкам, потому что я предполагаю, что слова открытых групп портов разделены не более чем одним или двумя пробелами, что неправильно. Если я попытаюсь поместить \ s *, тогда будет получена первая буква очистки и это неправильно. Есть что-то лучше?

Ответы [ 3 ]

0 голосов
/ 05 января 2019
var strings = new[] {
    "2011 Trieste MED clean/crude/crude",
    "2013 Trieste fo/crude/crude",
    "2013 Ningbo East Pacific cca/cf/ce",
    "2014 Agioi theodoroi MED cde/fo/ce"
};
var pattern = @"^\d+\s+(.+)(?=\s+.*?/)";
foreach (var s in strings)
{
    var match = Regex.Match(s, pattern);
    if (match.Success)
        WriteLine(match.Groups[1].Value);
    else
        WriteLine("No matches found.");
}
/*
Output:
    Trieste MED
    Trieste
    Ningbo East Pacific
    Agioi theodoroi MED
*/
0 голосов
/ 05 января 2019

Если вы позволите мне ...

Не каждая текстовая задача нуждается в Regex. Довольно часто вы можете просто использовать, например, Split() и некоторые другие целенаправленные заявления для достижения вашей цели. Это может быть намного легче сделать (и прочитать через 6 месяцев), чем пытаться превратить иногда нечитаемое регулярное выражение в представление.

Вот как:

public static void Main()
{
    var strings = new[] {"2011 Trieste MED clean/crude/crude",
                         "2013 Trieste fo/crude/crude",
                         "2013 Ningbo East Pacific cca/cf/ce",
                         "2014 Agioi theodoroi MED cde/fo/ce"};

    foreach (var s in strings)
        Console.WriteLine(GetName(s));
}

public static string GetName(string s)
{
    var allWords = s.Split(' ');
    var nameWords = allWords.Skip(1).Take(allWords.Length - 2);
    return string.Join(" ", nameWords);
}

Skip() и Take() - методы расширения Linq, доступные после добавления using System.Linq; в файл C #.

См. Это работает: https://dotnetfiddle.net/FTBcfC

0 голосов
/ 05 января 2019

Вы можете упростить свое регулярное выражение с этим,

^(?<YearBuilt>\d{4})\s+(?<OpenPort>.*)\s+(?<LastCargos>[^ ]+)$

Поскольку ваша первая вещь в строке - год, следовательно, используйте \d{4}, а последнее, что вы хотите сгруппировать, это что-то вроде clean/crude/crude, которое вы можете записать как [^ ]+ (что угодно, только не пробел) и тогда средний текст, образец которого подобен этому Ningbo East Pacific, может быть захвачен с помощью .*

Демо

Дайте мне знать, если это хорошо для вас, для других строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...