用于替换不在标签中的空格的正则表达式

时间:2012-07-12 06:45:07

标签: c# regex

我有一些自定义标签的纯文本。 例如:

I like C#. <code lang="C#">public static void main</code>
THis is good language.

我需要使用&nbsp;

替换不在标记内的所有空格

替换后的文字必须是:

I&nbsp;like&nbsp;C#.&nbsp;<code lang="C#">public static void main</code>
THis&nbsp;is&nbsp;good&nbsp;language.

3 个答案:

答案 0 :(得分:2)

如果您将有效的XML元素与文本混合在一起,则可以使用XML解析类,例如XDocument,您可以这样做:

        string input = @"I like C#. <code lang=""C#"">public static void main</code>THis is good language.";
        string rootedInput = String.Format("<root>{0}</root>", input);

        XDocument doc = XDocument.Parse(rootedInput);
        var nodes = doc.Root.DescendantNodes();

        StringBuilder sb = new StringBuilder();
        string nodeAsString = String.Empty;
        foreach (XNode node in nodes)
        {
            if (node.NodeType == XmlNodeType.Text)
                nodeAsString = node.ToString().Replace(" ", "&nbsp;");
            else
                nodeAsString = node.ToString();

            sb.Append(nodeAsString);
        }

        string newStr = sb.ToString();

答案 1 :(得分:1)

如果标签不能包含其他标签,并且没有自闭标签或其他奇怪的东西。这将有效。

使用perl表示法

s/ (?![^>]*\<\/)/&nbsp;/g

这也假定文件格式正确,并且开始和结束标记位于同一行(但您可以轻松地将其更改为多行正则表达式。)

以下是它的工作原理:

因为(如您所示)标签不能包含其他标签,因此在您不想替换的文本之后的某个时刻会有一个结束标记,所有结束标记都以</开头。这将在下一个开始标记之前发生。另一方面,您想要替换的文本将在下一个结束标记之前跟一个开始标记。

所以这只是匹配一个空格,然后做出一个负面的前瞻性预测,以确保下一次</出现在>之前(或开始标记的结尾。如果是是的,那么匹配就不会发生,空间也不会被替换。

仅当代码不能包含其他代码时才会有效。

答案 2 :(得分:0)

一个简单的想法!这有效:

String ConvertString(String inputString)
{
    var first = new List<string>();
    var second = new List<string>();

    foreach (Match match in Regex.Matches(inputString, "(?<inTag><code[^>]+>[^<]*</code[^>]+>)"))
    {
        first.Add(match.Groups["inTag"].Value);
    }

    inputString = inputString.Replace(" ", "&nbsp;");

    foreach (Match match in Regex.Matches(inputString, "(?<inTag><code[^>]+>[^<]*</code[^>]+>)"))
    {
        second.Add(match.Groups["inTag"].Value);
    }

    for (int i = 0; i < first.Count(); i++)
    {
        inputString = inputString.Replace(second[i], first[i]);
    }

    return inputString;
}