【问题标题】:Replace & with & in C#在 C# 中用 & 替换 &
【发布时间】:2019-03-28 05:12:15
【问题描述】:

好吧,我觉得问这个真的很愚蠢。我看到很多其他问题与我的问题相似,但似乎没有人能够回答。

我正在为一个对语法非常挑剔的程序创建一个 xml 文件。可悲的是,我正在从头开始制作 XML 文件。意思是,我将每一行单独放入(很多 file.WriteLine(String))。

我知道这很丑陋,但这是我能够让逻辑发挥作用的唯一方法。

无论如何。我有一些带有“&”的字符串。

if (value.Contains("&"))
   {
      value.Replace("&", "&");
   }

似乎不起作用。 value.Contains() 似乎看到了,但替换不起作用。我正在使用 C# .Net 2.0 sp2。与 2005 年相比。

请帮帮我..这是漫长的一周..

【问题讨论】:

  • 我感受到你的痛苦。不久前,我不得不生成一些 XML 发送给 编写了他们自己的 XML 解析器的第 3 方(不寒而栗),当然他们不支持某些重要功能,例如空格、cmets、处理指令等!
  • 是的,我正在为另一个程序编写一个“答案”文件。这些答案文件是由他们自己的专有软件创建的。以正确的顺序获取所有正确的数据然后以非常特定的 xml 格式输出是很棘手的。
  • 您还需要将 <>', ', and "` 字符替换为其 XML 字符实体等效项。
  • 涉及TrimMakeUpper 以及几乎所有其他现有字符串操作函数的问题的重复。也许这些东西需要进入 wiki 的 string-manipulation 标签。
  • @Ben Voigt - 抱歉,我现在知道这是重复的。我认为它是独一无二的,因为当时我认为 & 是某种奇怪的转义字符。请原谅重复的问题。

标签: c# string


【解决方案1】:

如果你真的想走那条路,你必须将Replace的结果(该方法返回一个新字符串,因为字符串是不可变的)分配回变量:

value = value.Replace("&", "&");

我建议您重新考虑编写 XML 的方式。如果您切换到使用XmlTextWriter,它将为您处理所有编码(不仅是&符号,还有所有其他需要编码的字符):

using(var writer = new XmlTextWriter(@"C:\MyXmlFile.xml", null))
{
    writer.WriteStartElement("someString");
    writer.WriteText("This is < a > string & everything will get encoded");
    writer.WriteEndElement();
}

应该产生:

<someString>This is &lt; a &gt; string &amp; 
    everything will get encoded</someString>

【讨论】:

  • 天啊..现在我觉得自己很愚蠢..我应该小睡一下。谢谢
  • 使用 .Replace 的一个问题是文本同时包含正确的 XML 实体和和错误 & 如果您控制 XML 生成,XmlTextWriter 绝对是最好的。在您无法控制 XML 生成的情况下,请参阅我的答案以获得更安全的解决方案。
【解决方案2】:

你真的应该使用 Linq to XML (XDocument 等) 来解决它。我 100% 确定你可以在没有你所有的 WriteLine´s 的情况下做到这一点;)向我们展示你的逻辑?

否则你可以使用它来防弹(而不是.Replace("&amp;")):

var value = "hej&hej<some>";
value = new System.Xml.Linq.XText(value).ToString(); //hej&amp;hej&lt;some&gt;

这也将处理&lt;,你也必须逃脱:)

更新:我查看了XText.ToString() 的代码,它在内部创建了一个XmlWriter + StringWriter 并使用XNode.WriteTo。对于给定的应用程序,这可能是多余的,因此如果要转换许多字符串,XText.WriteTo 会更好。 System.Web.HttpUtility.HtmlEncode 是一个快速且可靠的替代方案。

更新 2:我发现这个 System.Security.SecurityElement.Escape(xml) 可能是最快的并确保最大的兼容性(从 .Net 1.0 开始支持,不需要 System.Web 参考)。

【讨论】:

  • 我相信你是对的。根据我从另一个 xml 文档中提取的值的类型,生成的 XML 文档的结构会发生很大变化。有点难以解释,但我会记下你的建议,所以一旦我通过了这个“立即完成”阶段,我实际上可以让它变得不难看。谢谢
  • 虽然你错过了代码的实际问题,但我会给你一个+1建议XText。
  • 只是一个注释。我被困在使用 .Net 2.0 sp2 中。我是否可以假设 Linq 是 >=3.0 功能?
  • @Ian 它在 .Net 2.0 中不存在。您可能想改用 HtmlEncode :) 该站点显示了一些选项:weblogs.sqlteam.com/mladenp/archive/2008/10/21/…
  • @lasseespeholt 是的,这可能是我最好的选择。比巨大的多替换语句要好得多。谢谢
【解决方案3】:

您也可以使用 System.Web 命名空间下的 HttpUtility.HtmlEncode 类,而不是自己进行替换。 给你:http://msdn.microsoft.com/en-us/library/73z22y6h.aspx

【讨论】:

  • 请注意,尽管此类不在 ClientProfile 中
【解决方案4】:

您只能在节点值中使用正则表达式替换字符“&”:

输入数据示例(字符串)

<select>
 <option id="11">Gigamaster&Minimaster</option>
 <option id="12">Black & White</option>
 <option id="13">Other</option>
</select>

用正则替换

 Regex rgx = new Regex(">(?<prefix>.*)&(?<sufix>.*)<");
 data = rgx.Replace(data, ">${prefix}&amp;${sufix}<");

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(data);

结果数据

<select>
 <option id="11">Gigamaster&amp;MiniMaster</option>
 <option id="12">Black &amp; White</option>
 <option id="13">Other</option>
</select>

【讨论】:

    【解决方案5】:

    显然很晚了,但正确的答案是:

    System.Text.RegularExpressions.Regex.Replace(input, "&(?!amp;)", "&amp;");
    

    希望这对某人有所帮助!

    【讨论】:

    • 这是我发现的解决此问题的唯一有效解决方案。谢谢。
    • 如果您有其他 xml 实体(如 ')将无法工作。在这种情况下,它将被替换为:&apos;
    • @Trygve,这个问题特别与 &
    • @GonzaOviedo,是的,但重要的是要注意避免不必要的副作用。恕我直言,处理所有可能的情况总是好的。
    【解决方案6】:

    你可以试试:

    value = value.Replace("&", "&amp;");
    

    【讨论】:

      【解决方案7】:

      字符串是不可变的。你需要写:

      value = value.Replace("&", "&amp;");
      

      请注意,如果您这样做并且您的字符串包含"&amp;amp;",它将被更改为"&amp;amp;amp;"

      【讨论】:

      • 是的,我会确保在 if 语句中进行测试。谢谢
      • 或者"&amp;amp;amp;",如果它是一个 XML 教程,这可能是你想要的。
      【解决方案8】:

      我创建了以下函数来编码 & 和 ' 而不会弄乱已经编码的 & 或 ' 或 "

          public static string encodeSelectXMLCharacters(string xmlString)
          {
              string returnValue = Regex.Replace(xmlString, "&(?!quot;|apos;|amp;|lt;|gt;#x?.*?;)|'",
                  delegate(Match m)
                  {
                      string encodedValue;
                      switch (m.Value)
                      {
                          case "&":
                              encodedValue = "&amp;";
                              break;
                          case "'":
                              encodedValue = "&apos;";
                              break;
                          default:
                              encodedValue = m.Value;
                              break;
                      }
      
                      return encodedValue;
                  });
              return returnValue;
          }
      

      【讨论】:

      • 我相信表达式有一个小错误。一个 |最后缺少:这有效“&(?!”|’|amp;|lt;|gt;|#x?.*?;)|'”
      【解决方案9】:

      不确定这是否对任何人有用...我为此奋斗了一段时间...这是一个出色的正则表达式,您可以使用它来修复所有链接、javascript、内容。我不得不处理大量没人愿意纠正的遗留内容。

      将此添加到您的母版页中的渲染覆盖,控制或重新编码以通过它运行字符串。请不要因为我把它放在错误的地方而激怒我:

      // remove the & from href="blaw?a=b&b=c" and replace with &amp; 
      //in urls - this corrects any unencoded & not just those in URL's
      // this match will also ignore any matches it finds within <script> blocks AND
      // it will also ignore the matches where the link includes a javascript command like
      // <a href="javascript:alert{'& & &'}">blaw</a>
      html = Regex.Replace(html, "&(?!(?<=(?<outerquote>[\"'])javascript:(?>(?!\\k<outerquote>|[>]).)*)\\k<outerquote>?)(?!(?:[a-zA-Z][a-zA-Z0-9]*|#\\d+);)(?!(?>(?:(?!<script|\\/script>).)*)\\/script>)", "&amp;", RegexOptions.Singleline | RegexOptions.IgnoreCase);
      

      它是一个渲染页面的宽泛描边,但它可以适应多种用途而不会炸毁你的页面。

      【讨论】:

        【解决方案10】:

        怎么样

        Value = Server.HtmlEncode(Value);
        

        【讨论】:

          【解决方案11】:

          我很确定如果你用 CDATA “拥抱”你的价值,它会起作用,所以结果类似于

          <ampersandData><![CDATA[value with ampersands like &hellip;]]></ampersandData>
          

          希望对您有所帮助。
          迈克尔

          【讨论】:

            【解决方案12】:

            这里已经很晚了,但我想分享我的解决方案,它可以处理文档中除了其他 xml 字符实体之外同时具有 &(不正确的 xml)和 &(有效的 xml)的情况。

            此解决方案仅适用于您无法控制 xml 生成的情况,通常是因为它来自某些外部源。如果您控制 xml 生成,请按照@Justin Niessner 的建议使用 XmlTextWriter

            它也非常快,可以处理所有不同的 xml 字符实体/引用

            预定义字符实体:

            "

            &

            '

            >

            数字字符实体/引用:

            nnnn;

            hhhh;

            PS! & 后面的空格不应包含在实体/引用中,我只是在此处添加它以避免在页面渲染中对其进行编码

            代码

                public static string CleanXml(string text)
                {
                    int length = text.Length;
                    StringBuilder stringBuilder = new StringBuilder(length);
            
                    for (int i = 0; i < length; ++i)
                    {
                        if (text[i] == '&')
                        {
                            var remaining = Math.Abs(length - i + 1);
                            var subStrLength = Math.Min(remaining, 12);
                            var subStr = text.Substring(i, subStrLength);
                            var firstIndexOfSemiColon = subStr.IndexOf(';');
                            if (firstIndexOfSemiColon > -1)
                                subStr = subStr.Substring(0, firstIndexOfSemiColon + 1);
                            var matches = Regex.Matches(subStr, "&(?!quot;|apos;|amp;|lt;|gt;|#x?.*?;)|'");
                            if (matches.Count > 0)
                                stringBuilder.Append("&amp;");
                            else
                                stringBuilder.Append("&");
                        }
                        else if (XmlConvert.IsXmlChar(text[i]))
                        {
                            stringBuilder.Append(text[i]);
                        }
                        else if (i + 1 < length && XmlConvert.IsXmlSurrogatePair(text[i + 1], text[i]))
                        {
                            stringBuilder.Append(text[i]);
                            stringBuilder.Append(text[i + 1]);
                            ++i;
                        }
                    }
            
                    return stringBuilder.ToString();
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-06-12
              • 2016-12-04
              • 1970-01-01
              • 2015-09-11
              • 1970-01-01
              • 1970-01-01
              • 2010-10-13
              相关资源
              最近更新 更多