反转带有转义字符的字符串

时间:2017-11-30 15:03:49

标签: c# string reverse

我有一个可能包含转义字符的字符串。我们假设这是' \#39;。我按照MSDN Escape Sequences definition

我想要反转此字符串,但保留转义序列。

示例:

string input = @"Hello\_World";
string reversed = @"dlroW\_elloH";

请注意,在我的输入字符串中,反斜杠是单独的字符。反向字符串意味着在SQL LIKE语句中使用,其中下划线不是通配符,而是字面上的下划线。 SQL LIKE中的反斜杠用作转义字符

问题是,如果原始字符串中的字符前面有反斜杠,那么在我的反向字符串中,这个反斜杠应该仍然在字符之前:@" _" (两个单独的字符)应该反过来仍然是@" _"。

奖励积分:反向转义序列号码' \ 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];
}

这很有效。但是,我的字符串被转换为数组/列表两次。我想知道是否会有一种更聪明的方法,不必经常访问这些元素?

另外:无论如何我的问题是什么?

评论建议添加有关我的问题的更多信息。

当操作员在文本框中键入时,需要显示匹配元素的列表。他能看到的大多数元素都以类似的前缀开头。操作员搜索的差异在名称的末尾。

因此,我们希望显示带有键入字符的名称结尾的列表。因此,如果运营商输入&#34; World&#34;他会看到一个名单,其中所有名字都以&#34; World&#34;。

结尾

现有的数据库(更改无可置疑)有一个包含NAME和REVERSEDNAME的表。软件注意如果插入或更新名称,则插入/更新正确的反向名称。 REVERSEDNAME已编入索引,因此使用具有反转名称的WHERE很快。

因此,如果我需要返回以&#34; World&#34;结尾的所有名称,我需要返回REVERSEDNAME开头的所有记录的名称,反之为&#34; WORLD&#34;:

SELECT TOP 30 [MYTABLE].[NAME] as Name
FROM [MYTABLE]
WHERE [MYTABLE].REVERSEDNAME LIKE 'dlroW%'

只要不使用通配符(如下划线),这样就可以正常工作。这是由软件通过转义下划线字符解决的(我知道,糟糕的设计,SQL LIKE使用下划线作为外卡不应该透过,但我必须使用现有的软件)

所以操作员键入@&#34; My_World&#34; 我的软件收到了@&#34; My_World&#34;,反斜杠是一个单独的字符 我必须转向@&#34; dlrow_yM&#34;,请注意反斜杠仍在下划线之前

我的Dapper代码:

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});
}

MSDN about using escape characters in SQL LIKE

将转义字符更改为其他字符并不起作用。问题不在于转义字符是反斜杠,而是反转我的字符串应该将转义字符保留在转义字符的前面。

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

1 个答案:

答案 0 :(得分:2)

您可以使用正则表达式:

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());

模式包括格式的单个字符和转义序列:

\x????
\x??
\???
\?