.NET REGEX-获取不匹配模式的字符串的一部分



我有这个字符串

TEST_TEXT_ONE_20112017

我想消除_20112017,这是一个下划线的数字,这些数字可能会有所不同。我的目标是只有

TEST_TEXT_ONE

到目前为止,我有这个,但是我得到了整个字符串,我缺少一些东西吗?

Regex r = new Regex(@"bw+[0-9]+b");
MatchCollection words = r.Matches("TEST_TEXT_ONE_20112017");
foreach(Match word in words)
{
   string w = word.Groups[0].Value;
   //I still get the entire string
}

注释您的考虑:

  1. 您应该使用括号来标记组以捕获 - 或使用命名组。第一组(索引= 0)是整个比赛。您可能需要索引= 1。
  2. w代表单词字符,它已经包括下划线和数字。如果要在数字之前匹配任何内容,则应考虑使用.而不是w
  3. 默认情况下, +是贪婪的,您的w+将消耗您的最后一个未签名,除最后一个数字外。您可能想在最后一个数字之前明确需要下划线。
  4. 我建议您考虑是否要找到匹配的子字符串或整个字符串匹配。如果是后者,请考虑使用开始和终点标记:^$
  5. 如果您知道要消除8位数字,那么您可以像d{8}
  6. 一样给出明确的计数

例如,这应该有效:

Regex r = new Regex(@"^(.+)_d+$");
MatchCollection words = r.Matches("TEST_TEXT_ONE_20112017");
foreach (Match word in words)
{
    string w = word.Groups[1].Value;
}

替代

使用零宽的阳性lookahead断言构造,不捕获下一步。这使用(?=stuff)上的语法。因此,您可以使用较短的代码,并避免完全分组冲浪:

Regex r = new Regex(@"^.+(?=_d+$)");
String result = r.Match("TEST_TEXT_ONE_20112017").Value;

请注意,我们需要在正lookahead组中端标记$

Regex r = new Regex(@"(b.+)_([0-9]+)b");
String w = r.Match("TEST_TEXT_ONE_20112017").Groups[1].Value; //TEST_TEXT_ONE

或:

String w = r.Match("TEST_TEXT_ONE_20112017").Groups[2].Value; //20112017

我认为这似乎有点过高。作为替代方案,您可以在_字符上分开并重建字符串:

private static string RemoveDate(string input)
{
    string[] parts = input.Split('_');      
    return string.Join("_", parts.Take(parts.Length - 1));
}

或日期后缀总是相同的长度,您也只需substring:

private static string RemoveDateFixedLength(string input)
{
    //Removes last 9 characters (8 for date, 1 for underscore)
    return input.Substring(0, input.Length - 9);
}

但是我觉得第一种方法更好,这只是另一种选择。

小提琴