如何在一行代码中逃避所有逃脱的角色?

时间:2014-06-04 21:10:19

标签: c# regex string escaping stringescapeutils

基于我所看到的here(接受的答案),似乎我可以通过这样做来逃避字符串:

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

...但是逐步完成,我发现s和t之间没有区别(我希望我能看到" Woolworth' s"作为t的值而不是& #34; Woolworth"两个vars)。

我想,我可以这样做:

    string s = "Woolworth's";
    s = s.Replace("'", "\'");

...etc., also escaping the following: [, ^, $, ., |, ?, *, +, (, ), and \

...但是一站式购物"解决方案更可取。

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

例如,它扼杀了这个:

<item>Woolworth's</item>

......需要这样:

<item>Woolworth\'s</item>

4 个答案:

答案 0 :(得分:4)

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

  

通过将其替换为转义码来转义一组最小字符(\,*,+,?,|,{,[,(,),^,$ ,.,#和空格)。这指示正则表达式引擎按字面解释这些字符而不是元字符。


匹配/捕获您想要转义的字符类字符(请注意,某些字符在字符类中具有特殊含义,需要像\-一样进行转义):

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

然后用反斜杠和对要转义的角色的引用替换它:

\\1

Demo


在C#中:

string s = "Woolworth's";
Regex rgx = new Regex("(['^$.|?*+()\\\\])");

string t = rgx.Replace(s, "\\$1");
// Woolworth\'s

Demo

答案 1 :(得分:2)

Regex.Escape 适合此上下文。

它是专门为正则表达式设计的,并且会为这个上下文逃避太多太少 - 试图将它踩到模型中可能会破坏其他值。 (它不会转义'",因为这些字符在.NET正则表达式中没有特殊含义。)

这里的相关内容是String Resource File中的Item Element对文本进行了一些特殊的解析(与格式相关)在从XML读取之后:

  

如果字符串中有撇号或引号,则必须将其转义或将整个字符串括在其他类型的引号中。

因此,在这种情况下适合的转换只是

s.Replace("'", "\'").Replace("\"", "\\\"")

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

(然后,假设XML正在通过DOM或LINQ to XML正确构建,XML编码在其他地方得到了解决 - 尽管使用格式化与混合内容样式时规则更复杂。)

答案 2 :(得分:1)

有不同种类的角色逃避。在您链接的问题中,他们正在谈论为正则表达式转义,它们有自己的一组特殊字符。

如果你专门想要转义XML的文本,你可能想要查看System.Xml命名空间中的XmlConvert Class。有了它,你可以使用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

答案 3 :(得分:1)

在“一行代码”中实现某些目标的最佳方法是在某处编写一个方法,使 正确 完成工作,然后从那一刻开始你调用那个方法的时候,把自己想象成“在一行代码中”。

接受的答案似乎似乎来做这个伎俩,但它会因控制字符(例如换行符)或任何其他可能由于各种原因而无法打印的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();
}