如何在一行代码中转义所有值得转义的字符?

本文关键字:转义 值得 字符 代码 一行 | 更新日期: 2023-09-27 18:06:50

根据我在这里看到的(公认的答案),我似乎可以这样做来转义字符串:

string s = "Woolworth's";
string t = Regex.Escape(s);
MessageBox.Show(t);

…但是经过这一步,我看不出s和t之间有什么区别(我希望我能看到"Woolworth’s"作为t的值,而不是两个变量的"Woolworth’s")。

我想,我可以这样做:

    string s = "Woolworth's";
    s = s.Replace("'", "''");
...etc., also escaping the following: [, ^, $, ., |, ?, *, +, (, ), and '

…但"一站式购物"的解决方案更可取。

更具体地说,我需要用户输入的字符串是Android arrays.xml文件中可接受的字符串值。

例如:

<item>Woolworth's</item>

…它应该是这样的:

<item>Woolworth''s</item>

如何在一行代码中转义所有值得转义的字符?

Regex.Escape()只转义正则表达式保留字符:

逃最小的一组字符 (', *, +, ?, |, {, [, (,), ^, $,., #和空格),将它们替换为它们的转义码。这指示正则表达式引擎按字面意思解释这些字符,而不是作为元字符。


匹配/捕获您想要转义的字符的字符类(注意,某些字符在字符类中具有特殊含义,需要转义,如'-):

(['^$.|?*+()''])

然后将其替换为反斜杠和要转义的字符的引用:

''1


在c#:

string s = "Woolworth's";
Regex rgx = new Regex("(['^$.|?*+()''''])");
string t = rgx.Replace(s, "''$1");
// Woolworth''s

Regex.Escape 适合这种情况。

它是严格为正则表达式设计的,在这种情况下会转义过多的过少的——试图将其硬塞进模型可能会破坏其他值。(它不会转义'",因为这些字符在. net正则表达式中没有特殊意义。)

这里的相关性是字符串资源文件中的Item元素对文本进行一些特殊的解析(与格式相关)之后,它从XML中读取:

如果字符串中有撇号或引号,则必须对其进行转义,或者将整个字符串用其他类型的引号括起来。

因此,在这种上下文中适合的转换就是
s.Replace("'", "''").Replace("'"", "'''"")

Regex.Replace(s, "[''"]", "''$&")

(然后,假设XML是通过DOM或LINQ to XML正确构建的,那么XML编码将在其他地方处理—尽管使用格式与混合内容样式时规则更复杂)

有不同类型的字符转义。在你链接到的问题中,他们谈论的是正则表达式的转义,正则表达式有自己的一组特殊字符。

如果您特别希望将文本转义为XML,则可能需要查看System.Xml名称空间中的XmlConvert类。有了它,您可以使用XmlConvert转义字符。EncodeName并使用XmlConvert检索字符。DecodeName:

    string s = "Woolworth's";
    string encoded = XmlConvert.EncodeName(s); // Value here is Woolworth_x0027_s
    string decoded = XmlConvert.DecodeName(encoded); // Value here is Woolworth's

实现"一行代码"的最佳方法是在某处编写一个方法,正确地完成然后从那一刻起,每次调用该方法时,都认为自己在"一行代码"中完成了它。

可接受的答案似乎可以解决问题,但是对于诸如换行之类的控制字符或任何其他可能由于各种原因不可打印的unicode字符,它将失败。

下面的方法将执行与StringEscapeUtils.escapeForJava()相同的操作。

我发布它主要是为了人们在未来偶然发现这个问题,寻找这个非常常见问题的答案。

public static String escapeForJava( String value, boolean quote )
{
    StringBuilder builder = new StringBuilder();
    if( quote )
        builder.append( "'"" );
    for( char c : value.toCharArray() )
    {
        if( c == '''' )
            builder.append( "'''" );
        else if ( c == ''"' )
            builder.append( "'''"" );
        else if( c == ''r' )
            builder.append( "''r" );
        else if( c == ''n' )
            builder.append( "''n" );
        else if( c == ''t' )
            builder.append( "''t" );
        else if( c < 32 || c >= 127 )
            builder.append( String.format( "''u%04x", (int)c ) );
        else
            builder.append( c );
    }
    if( quote )
        builder.append( "'"" );
    return builder.toString();
}