C# 使用转义字符反转字符串

C# 使用转义字符反转字符串,c#,string,reverse,C#,String,Reverse,我有一个可能包含转义字符的字符串。让我们假设这是“\”。我遵循 我想反转这个字符串,但保留转义序列 例如: string input = @"Hello\_World"; string reversed = @"dlroW\_elloH"; 请注意,在我的输入字符串中,反斜杠是独立的字符。反向字符串用于类似SQL的语句中,其中下划线不是通配符,而是字面上的下划线。类SQL中的反斜杠用作转义字符 问题是,如果原始字符串中的某个字符前面有反斜杠,那么在我的反向字符串中,该反斜杠仍应位于该字符前面:

我有一个可能包含转义字符的字符串。让我们假设这是“\”。我遵循

我想反转这个字符串,但保留转义序列

例如:

string input = @"Hello\_World";
string reversed = @"dlroW\_elloH";
请注意,在我的输入字符串中,反斜杠是独立的字符。反向字符串用于类似SQL的语句中,其中下划线不是通配符,而是字面上的下划线。类SQL中的反斜杠用作转义字符

问题是,如果原始字符串中的某个字符前面有反斜杠,那么在我的反向字符串中,该反斜杠仍应位于该字符前面:@“u”(两个单独的字符)的反向位置仍应为@“u”

加分:用数字“\x0128”反转转义序列

我尝试过将其作为扩展函数:

public static string EscapedReverse(this string txt, char escapeChar)
{
    IList<char> charList = txt.ToList();
    return new string(EscapedReverse(charList, escapeChar).ToArray());
}

public static IEnumerable<char> EscapedReverse(this IList<char> text, char escapeChar)
{
    int i = text.Count-1;
    // Text[i] is the last character of the sequence;
    // text[i] is the next character to return, except if text[i-1] is escapeChar
    while (i > 0)
    {
        if(text[i-1] == escapeChar)
        {
            yield return text[i-1];
            yield return text[i];
            i -= 2;
        }
        else
        {
            yield return text[i];
            i -= 1;
        }
    }
    // return the last character
    if (i == 0)
        yield return text[i];
}
只要不使用通配符(如下划线),这就可以正常工作。软件通过转义下划线字符解决了这个问题(我知道,糟糕的设计,SQL-LIKE使用下划线作为通配符的事实不应该渗透进来,但我不得不接受这个现有的软件)

因此操作员键入“我的世界” 我的软件收到@“我的世界”,反斜杠是一个单独的字符 我必须反转为@“dlrow_yM”,注意反斜杠仍然在下划线之前

我的简洁代码:

IEnumerable<string> FetchNamesEndingWith(string nameEnd)

// here is my reversal procedure:
string reversedNameEnd = nameEnd.EscapedReverse() = '%';

using (var dbConnection = this.CreateOpenDbConnection())
{
    return dbConnection.Query<string>(@"
        SELECT TOP 30 [MYTABLE].[NAME] as Name
        FROM [MYTABLE]
        WHERE [MYTABLE].REVERSEDNAME LIKE @param ESCAPE '\'",
        new {param = reversedNameEnd});
}
IEnumerable FetchNamesEndingWith(字符串nameEnd)
//以下是我的撤销程序:
字符串reversedNameEnd=nameEnd.EscapedReverse();
使用(var dbConnection=this.CreateOpenDbConnection())
{
返回dbConnection.Query(@)
选择前30名[MYTABLE].[NAME]作为名称
从[MYTABLE]
其中[MYTABLE].REVERSEDNAME类似于@param ESCAPE'\'”,
新的{param=reversedNameEnd});
}

将转义字符更改为其他字符没有帮助。问题不是转义字符是反斜杠,而是反转字符串应该使转义字符位于转义字符前面


我的代码运行正常,我只是想知道是否有更好的算法不会复制字符串两次。不仅是针对这个特定问题,而且如果将来出现问题,我需要反转字符串并保留某些字符。

您可以使用正则表达式:

var pattern =  @"\\x[1-9a-fA-F]{4}|\\x[1-9a-fA-F]{2}|\\[0-7]{3}|\\.|.";
var rgx = new Regex(pattern);
return new string(
          rgx.Matches(txt)
          .Cast<Match>()
          .OrderByDescending(x => x.Index)
          .SelectMany(x => x.Value)
          .ToArray());

您可以使用正则表达式:

var pattern =  @"\\x[1-9a-fA-F]{4}|\\x[1-9a-fA-F]{2}|\\[0-7]{3}|\\.|.";
var rgx = new Regex(pattern);
return new string(
          rgx.Matches(txt)
          .Cast<Match>()
          .OrderByDescending(x => x.Index)
          .SelectMany(x => x.Value)
          .ToArray());


如果你的方法有效,那么问题就离题了,你可能想把它放在旁注上:为什么你的方法接受
IList
而不是
string
。整个方法仍然有效,您不必从文本创建列表来调用它。如果字符串是这样定义的,那么您的反斜杠不会出现在字符串中,因为
\t
表示制表符和
\“
表示报价。你确定你这里有问题吗?你能发布一个吗?你是对的,忘记添加介绍@。问题是SqlCommand在LIKE中带有下划线,表示通配符。我想匹配一个名字的结尾部分,所以我必须将类似的部分与相反的部分进行比较。我将根据您的方法编辑我的问题。如果您的方法有效,则问题不在主题范围内,您可能希望将其张贴在旁注上:为什么您的方法接受
IList
而不是
string
。整个方法仍然有效,您不必从文本创建列表来调用它。如果字符串是这样定义的,那么您的反斜杠不会出现在字符串中,因为
\t
表示制表符和
\“
表示报价。你确定你这里有问题吗?你能发布一个吗?你是对的,忘记添加介绍@。问题是SqlCommand在LIKE中带有下划线,表示通配符。我想匹配一个名字的结尾部分,所以我必须将类似的部分与相反的部分进行比较。我将根据正确答案编辑我的问题!我建议将模式改为“\(a | b | f | n | r | t | v |?”“\ \ |\?[0-7]{3}(x[0-9a-fA-f]{4}(x[0-9a-fA-f]{2}”)。”因此它只会对msdn@GuyMontag实际依据:如果表格中未出现的字符前面有反斜杠,编译器将未定义的字符作为字符本身进行处理。因此,您的建议将对单字母转义序列产生无效结果。很好地捕捉到\x值上的十六进制。公平点。最后一件事:我认为第三种选择应该是\[0-7]{3},以便只匹配三位数ASCII的八进制数-characters@GuyMontag是的。代码可能较短,但对于审阅者来说,检查起来要困难得多。正则表达式的复制速度会比我当前代码的复制速度快一倍吗?回答得好!我建议将模式改为“\(a | b | f | n | r | t | v |?”“\ \ |\?[0-7]{3}(x[0-9a-fA-f]{4}(x[0-9a-fA-f]{2}”)。”因此它只会对msdn@GuyMontag实际依据:如果表格中未出现的字符前面有反斜杠,编译器将未定义的字符作为字符本身进行处理。因此,您的建议将对单字母转义序列产生无效结果。很好地捕捉到\x值上的十六进制。公平点。最后一件事:我认为第三种选择应该是\[0-7]{3},以便只匹配三位数ASCII的八进制数-characters@GuyMontag是的。代码可能较短,但对于审阅者来说,检查起来要困难得多。正则表达式的复制速度会比当前代码快两倍吗?
\x????
\x??
\???
\?