正则表达式-介于两者之间的单词数量未知

时间:2019-01-05 18:46:50

标签: c# regex

我有以下字符串

  • 2011年的里雅斯特MED干净/原始/原始
  • 2013 Trieste fo / crude / crude
  • 2013宁波东太平洋cca / cf / ce
  • 2014年Agioi theodoroi MED cde / fo / ce

我实际上想做的是尝试将的里雅斯特MED(第一串),的里雅斯特(第二串),宁波东太平洋(第三串)和agioi theodoroi med(第四串)作为一个开放港口来捕获。通常在2013年日期之间有1到4个字,例如和原油/原油/原油。

这是我到目前为止尝试过的https://regex101.com/r/mYevqd/1

但是这很容易出错,因为我仅假设开放端口组的字由一个或两个最大空格分隔,这是错误的。如果我尝试放置\ s *,则将捕获第一个干净的字母这是错误的。有更好的东西吗?

3 个答案:

答案 0 :(得分:1)

您可以以此简化您的正则表达式,

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

由于字符串中的第一件事是一年,因此请使用\d{4},最后要分组的内容是这样的clean/crude/crude,您可以将其捕获为[^ ]+(任何东西,但没有空格),然后可以使用Ningbo East Pacific

捕获示例为.*的中间文本

Demo

让我知道这对于其他字符串是否还行得通。

答案 1 :(得分:0)

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
*/

答案 2 :(得分:0)

如果您允许我...

并非每个基于文本的问题都需要使用正则表达式。通常,您只能使用Split()和其他一些目的驱动的陈述以实现您的目标。这比尝试击败有时难以理解的Regex提交要容易得多(并在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