替换所有出现和正则表达式

时间:2011-02-16 00:12:12

标签: c# regex

我正在尝试使用HTML标记<p/>替换两个连续的换行符。所以在一个字符串中如:

\r\n\r\n\r\n

连续两次出现\r\n\r\n

结果应为:

<p/><p/>

但是使用C#String.Replace,它只会检测到第一次出现而我才会回来:

<p/>\r\n

所以我想知道是否有正则表达式大师知道如何使用正则表达式检测它?

修改

我认为这个问题有点令人困惑。让我重新说一下。要求应该是在标记"\r\n"之前替换任何<p/>,只有在它之前还有另一个“\ r \ n”时。

使用字符串:

\r\n\r\n\r\n
  • 第一个\r\n,之前没有其他\r\n,不应该做任何事,
  • 第二个\r\n,它之前有另一个\r\n,有资格替换,
  • 第三个\r\n,它之前有另一个\r\n,也有资格替换。

所以结果应该是:

<p/><p/>

4 个答案:

答案 0 :(得分:5)

是的,您可以使用正则表达式执行此操作:

string tidyString = Regex.Replace(originalString, @"(?<=\r\n)\r\n", "<p/>");

如果性能是一个问题,那么可能发现手动重建字符串比正则表达式更快,但缺点是代码更复杂。 (我可能会在99%的情况下使用正则表达式。)

var sb = new StringBuilder(originalString.Length);
int startIndex = 0, nextIndex;
while ((nextIndex = originalString.IndexOf("\r\n", startIndex)) >= 0)
{
    if ((nextIndex == startIndex) && (startIndex > 0))
        sb.Append("<p/>");
    else
        sb.Append(originalString, startIndex, nextIndex - startIndex + 2);

    startIndex = nextIndex + 2;
}
sb.Append(originalString, startIndex, originalString.Length - startIndex);

string tidyString = sb.ToString();

答案 1 :(得分:1)

你在评论中说过这个:

  

我想要做的是,如果我发现了   “\ r \ n”就在“\ r \ n”之前,它   应该用标签“p”替换。

这可以改写:

  

如果我检测到 N ,我想要做的是   连续出现“\ r \ n”   其中 N&gt; 1 ,我想替换这些    N - 1 出现标记“p”。

不相信我?

假设我们有一些围栏帖子:

|  |  |  |  |

如果我说,“我想在另一个围栏岗位之前发现围栏的任何地方,”我真的在说什么?我说我想在有N个连续围栏的地方进行N - 1次检测(再次:当N> 1时)。

看看上面;有五个围栏帖子,但四个出现,例如您所描述的内容。在第一次出现之后检测连续出现的“\ r \ n”也是如此。


听起来不是用"\r\n\r\n"替换字符串"<p/>",而是希望在第一次出现后用{{1}替换所有出现的"\r\n" ,剥离第一次出现。 (您的示例包含两个连续出现的"<p/>";它包含三个连续出现的"\r\n\r\n"。)

如果这正是您想要的,我建议您执行我刚刚描述的操作:检测"\r\n"并使用{替换字符串中的后续 "\r\n"次出现{1}}(直到到达不同的文本块)。

如果您需要任何帮助,请告诉我。当然,我也可能误解了你;但这就是你想要完成的事情。

提示:一种非常简单但效率低下的方法是使用字符串"\r\n"作为分隔符调用"<p/>"并使用结果数组重建字符串。 / EM>

实际上,我认为上述提示不会让你到那里,即使是效率低下的解决方案。但是,显然还有其他方法。

答案 2 :(得分:1)

修改(原始答案已删除)

试试这个。我不得不使用第二种替换方法来满足第3次\ r \ n发生。

var input = "Line1\r\nLine2\r\n\r\n\r\n<line5>";
var result = Regex.Replace(input, "(\\r\\n){2}", "<p/>");
result = Regex.Replace(result, "<p/>\\r\\n", "</p></p>");

//result equals: "Line1\r\nLine2</p></p><line5>"

答案 3 :(得分:0)

"\r\n\r\n\r\n"实际上并非“连续两次出现"\r\n\r\n"”。是的,字符1-4和字符3-6都是字符串"\r\n\r\n",但它们彼此相交。 String.Replace无法将此考虑在内。它只是扫描字符串,直到找到要替换的内容,进行替换,然后继续从该点开始扫描字符串。它不会扫描整个字符串并识别要替换的各个子字符串,然后用指定的字符串替换它们。