【问题标题】:simple rookie regex help needed需要简单的菜鸟正则表达式帮助
【发布时间】:2012-02-27 16:47:04
【问题描述】:

我在下面有一个简单的正则表达式来提取由 end**end 包围的字符串中的值,例如下面的示例。然而,虽然这很简单,但我正在努力获得我需要的结果!有什么明显的我失踪了! 一如既往的感谢。

var str = "endhelloend";
var match = Regex.Match(str, @"end([a-z]+)end$", RegexOptions.IgnoreCase);

if(match.Success)
{
    result = match.Groups[0].Value  // should return 'hello'
}

【问题讨论】:

  • 您的正则表达式说只有字母可以在结尾和结尾之间。是这样吗?你能提供应该和不应该匹配的示例案例吗?
  • 你想从HTML文件中提取文本内容,是你想实现的吗?

标签: c# asp.net .net regex


【解决方案1】:

您的模式正确地包含您要提取的组。正则表达式匹配将包含一组供您访问的组。在您的示例中,请尝试以下操作:

var str = "endhelloend";
var match = Regex.Match(str, @"end([a-z]+)end$", RegexOptions.IgnoreCase);

if(match.Success)
{
    var hello = match.Groups[1];
}

match.Groups[0] 将返回整个匹配“endhelloend”,因此您只需要匹配中的第一个组。

【讨论】:

    【解决方案2】:

    match.Groups[0] 将匹配整个正则表达式 - 查看 match.Groups[1]。

    【讨论】:

    • 谢谢,但在调试 matchin.Success 时,结果为 false,因此 match.group 永远不会被所示示例命中
    • 您应该将该信息放在问题中。试试 [a-z]+?作为您的匹配组,看看是否有帮助。 + 默认情况下 iirc 是一个贪婪运算符,因此它可能匹配 end,因此找不到结束字符串。
    • 使+ 非贪婪应该没有任何效果。确实,贪婪的[a-z]+最初 消耗第二个end,但随后它会退后到足以让正则表达式的其余部分(end$)匹配它需要的。
    【解决方案3】:

    我认为这条线应该是这样的: result = match.Groups[1].Value;

    【讨论】:

      【解决方案4】:

      我看到您正在为此苦苦挣扎,因此我将提供一些见解。

      此正则表达式 end([a-z]+)end$ 将匹配此字符串“endhelloend”。
      内部文本将在捕获组 1 中。
      当它是这样的子字符串时,它不会匹配相同的字符串
      endhelloend of the world”。

      原因是你有一个字符串元字符结尾(断言)$ 作为正则表达式的一部分
      就在“结束”之后。

      所以你可以在正则表达式中取出$,它应该可以正常工作。
      不过,还有其他事情需要考虑。我会在你的正则表达式中评论它。

      end        // find a literal 'end'
      (          // Capture group 1 open
        [a-z]+   // Find as many characters a-z as possible (including 'e' 'n' 'd' ins sequence
      )          // Capture group 1 close
      end        // find a literal 'end'
      $          // End of string assertion (the last 'end' must be the last word in the string)
      

      【讨论】:

        【解决方案5】:

        使用solution 1提取.html文本内容,然后使用solution 2从文本中过滤您想要的文本。

        1. 要清理 .htm 文件中的 html 元素,请尝试以下操作:

          string CleanXml(string DirtyXml)
          {
              //string clean = ""; 
              int startloc = 0, endloc = 0;
          
              for (int x = 0; x <= DirtyXml.Length-1; x++)
              {
                  if (DirtyXml[x] == '<')
                  {
                      startloc = x;
                      x++;
                  }
                  if (DirtyXml[x] == '>')
                  {
                      endloc = x;
                      x++;
                      DirtyXml = DirtyXml.Remove(startloc, (endloc - startloc)+1);
                      x = 0;
                  }   
              }
              return DirtyXml;
          }
          
        2. 正则表达式过滤文本“endhelloend”以获得“hello”

              string result = "";
              var str = "endhelloend";
              var match = Regex.Match(str, @"end([a-z]+)end$", RegexOptions.IgnoreCase);
              if(match.Success)
              {
                  result = match.Groups[1].Value;  // Returns 'hello'
              }
              Console.WriteLine(result);
              Console.ReadLine();
          

        【讨论】:

        • var str = System.IO.File.ReadAllText(@"test.htm"); var match = Regex.Match(str, @"end([a-z]+)end$", RegexOptions.IgnoreCase); if (match.Success) { var result = match.Groups[1].Value; // 返回'你好' }
        • str 的内容是 " Hello endhelloend 这是一个例子 "
        • “test.htm”的内容是什么?
        • 从“test.htm”中提供最多三行的大样本,以便我提出解决方案。
        • 我在之前的评论中提供了整个 test.htm。
        【解决方案6】:

        试试这个,它会给你任何介于单词 end 之间的字母字符,但不会捕获实际的单词 end

        (?<=end)[a-z]+?(?=end)
        

        【讨论】:

        • 环视增加了不必要的复杂性,却没有带来任何好处。您的正则表达式将起作用,但这是因为您将$ 关闭(正如@sln 解释的那样),而不是因为环视。
        • @Alan Moore,我实际上故意遗漏了 $ (非):D,问题使用字符串 endhelloend 作为测试,而不是 endhelloend 123 455... 环视会带来什么样的复杂性?我没想到它的性能影响会这么大,恕我直言,这更漂亮match.Value
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-30
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多