【问题标题】:C#: RegEx Expression for Multiline TextBoxC#:多行文本框的正则表达式
【发布时间】:2012-09-13 00:45:07
【问题描述】:

基本上,我试图在多行文本框中找到以下模式:

[p]anyword bla bla anyword[/p]

1.) 该模式可以在文本框中出现 n 次,我也希望找到它 n 次。

2.) [p] 和 [/p] 之间可以是任何字符,包括空格和换行符(C# 中的“\r\n”)

3.) 我想要整个模式,包括 [p] 和 [/p]

以下代码非常接近我想要的结果。问题是,[p] 和 [/p] 之间可能会出现多个换行符。我已经尝试了很多很多解决方案。没有什么对我有用。

private void getTextFromTag2(String Tag, String txt)
{
    txt = txt.Replace("\r", "");

    string re1 = "(\\[";    
    string re2 = "p";   
    string re3 = "\\]"; 
    string re4 = ".*";  // Here lies the problem
    string re5 = "";    // Left open for a solution => \r\n cann occur n-times
    string re6 = "\\["; 
    string re7 = "\\/"; 
    string re8 = "p";   
    string re9 = "\\])";    

    Regex r = new Regex(re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9, RegexOptions.IgnoreCase | RegexOptions.Multiline);

    MatchCollection mc = r.Matches(txt, 0);

    foreach (Match match in mc)
    {
        String c1 = match.Groups[1].ToString();
        Console.Write(c1 + "\r\n");
    }

}

如您所见,我已经将 txt 中的“\r”替换为“”,因为 .NET 的 RegEx 引擎似乎只需要“\n”作为换行符。

我认为,我的代码中的问题是在 re4 和 re5 中找到的。 re4 找到任何字符并且工作良好,只要没有换行符。

我认为,re4 应该说“任何字符,包括空格和 \n”。但我真的不明白。

再一次:即使模式在文本框中多次出现,Everting 也能正常工作。问题是,当 [p] 和 [/p] 之间发生换行时

这是一个不起作用的例子

[p]BlaBla BlaBla \r\n
BlaBla BlaBla \r\n
\r\n
BlaBla
[/p]

这是一个有效的例子

[p]BlaBla BlaBla[/p]
\r\n
\r\n
[p]Even more BlaBla[/p]
\r\n
\r\n
[p]Much more BlaBla[/p]

请原谅我的英语。我不是以英语为母语的人。

谢谢。

这是现在对我有用的代码。改变的东西是 //Changed Tagged

private void getTextFromTag2(String Tag, String txt)
    {
        //txt = txt.Replace("\r", ""); //Changed

        string re1 = "(\\[";     
        string re2 = "p";    
        string re3 = "\\]";  
        string re4 = ".*";   
        string re5 = "?";   // Changed
        string re6 = "\\["; 
        string re7 = "\\/"; 
        string re8 = "p";   
        string re9 = "\\])";    

        Regex r = new Regex(re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline); //Changed

        MatchCollection mc = r.Matches(txt, 0);

        foreach (Match match in mc)
        {
            String c1 = match.Groups[1].ToString();
            Console.Write(c1 + "\r\n");
        }

    }

非常感谢。

【问题讨论】:

  • re5 似乎与评论不符。应该是“?”而不是“”(空字符串)?另外,您不期望嵌套块,对吗?即“[p]这个[p]不是[/p]有效[/p]”?
  • 没错。我的意图是让 re5 为解决方案敞开大门,因为我认为 re4 和 re5 是整个问题。正如您在示例中看到的那样,这不起作用,[p] 和 [/p] 之间可以有多个换行符
  • 目前整个 RegEx 看起来像这样:"(\[p\].*\[\\/p\])"

标签: c# regex line-breaks multiline


【解决方案1】:

您需要指定单行选项

指定单行模式。更改点 (.) 的含义,使其匹配每个字符(而不是除 \n 之外的每个字符)。

基本上,您可能在其他语言中熟悉的“点匹配全部”选项。您设置的多行选项仅影响匹配行的开头和结尾的行为。详情请见RegexOption class

Regex r = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.Singleline);

您提供的正则表达式的另一个问题是 * 是贪婪的。所以 [p][/p][p][/p] 将是一个匹配项(它在第一个 [p] 和最后一个 [/p] 上匹配。将你的 re5 更改为:

string re5 = "?";    // Non-greedy match on *

将解决此问题,以便您获得两个单独的匹配项。

【讨论】:

  • 感谢您的建议。如果您只有一个 [p][/p] 组,这似乎可行。我在文本框中尝试了多个组,然后 RegEx 将这两个组放在一起。您的解决方案离我想要的位置更近了,但它不起作用。
  • 这就是我对您的问题的评论发挥作用的地方。尝试将您的 re5 更改为问号以表示懒惰(非贪婪)
  • 耶啊啊啊啊啊啊!就是这样!这两个建议现在一起工作。非常感谢。在发布问题之前,我已经为此工作了几个小时。我将发布工作代码。非常感谢。
  • 您还应该考虑到您应该能够摆脱您的 txt.Replace 现在,除非您需要避免在匹配中使用 '\r'。不确定这是否重要,但这将有助于提高效率。
  • 是的,你完全正确。你可以在上面看到它,我是如何改变它的。我试过了,我必须改变它。不改变它,它就不起作用。
【解决方案2】:

. 匹配除换行符以外的任何字符。 \s 将匹配空格和换行符。

(.|\s)*

【讨论】:

  • 感谢您的回答。我会试试的。如您所见,此案已解决。您可以在案例本身中看到更改的代码。问候。
猜你喜欢
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
相关资源
最近更新 更多