【问题标题】:Escaping \x from strings从字符串中转义 \x
【发布时间】:2012-03-23 02:07:09
【问题描述】:

嗯,我有这个小方法:

static string escapeString(string str) {
    string s = str.Replace(@"\r", "\r").Replace(@"\n", "\n").Replace(@"\t", "\t");
    Regex regex = new Regex(@"\\x(..)");
    var matches = regex.Matches(s);
    foreach (Match match in matches) {
        s = s.Replace(match.Value, ((char)Convert.ToByte(match.Value.Replace(@"\x", ""), 16)).ToString());
    }

    return s;
}

它替换了我在 args[0] 中得到的字符串中的“\x65”。

但我的问题是:“\\x65”也将被替换,所以我得到“\e”。我试图找出一个正则表达式来检查是否有多个反斜杠,但我没有运气。

有人能给个提示吗?

【问题讨论】:

  • 你在重塑Regex.Unescape吗?
  • 为什么\\x65 不能变成\e
  • @bzlm: 因为第一个 \ 转义了第二个 \
  • 见鬼!那很简单!多谢! :)
  • 在问题中使用“gimme”这个词是非常不可取的。

标签: c# regex


【解决方案1】:

您可以继续破解正则表达式以及“\s|\w\x(..)”之类的内容,以删除 \x65 的大小写。显然这会很脆弱,因为不能保证您的序列 \x65 前面总是有一个空格或字符。它可能是文件的开头。此外,您的正则表达式将匹配 \xTT,这显然不是 unicode。考虑更换“。”具有像“\x([0-9a-f]{2})”这样的字符类。

如果这是一个学校项目,我会执行以下操作。您可以将“\”的所有组合替换为另一个不太可能的序列,例如“@!!@!!@”,运行正则表达式和替换,然后将所有不太可能的序列替换回“\ ”。例如:

String s = inputString.Replace(@"\\", @"_@!!@!!@_");
// do all of the regex, replacements, etc here
String output = s.Replace(@"_@!!@!!@_", @"\");

但是,您不应该在生产代码中这样做,因为如果您的输入流曾经有魔术序列,那么您将获得额外的反斜杠。

很明显,您正在编写一种插值器。我觉得有义务推荐研究一些更强大的东西,比如使用正则表达式形成有限状态机的词法分析器。 Wiki 上有一些关于这个主题的精彩文章,我是 ANTLR 的忠实粉丝。现在可能是过度设计,但如果您不断遇到这些特殊情况,请考虑以更一般的方式解决您的问题。

从这里开始阅读理论:http://en.wikipedia.org/wiki/Lexical_analysis

【讨论】:

    【解决方案2】:

    使用消极的回顾:

    Regex regex = new Regex(@"(?<!([^\]|^)\\)\\x(..)");
    

    这断言前一个字符不是一个单独的反斜杠,而是不捕获前一个字符(环顾不捕获)。

    【讨论】:

    • 这不会匹配\\\x65,但可能应该匹配。
    • @hvd 我考虑过,但希望没有人会注意到 :) 我想我已经解决了。
    • 现在它匹配字符串开头的\\x65 中的\x(因为它前面没有[^\]\\ ),它也匹配\\\\x65。如果反斜杠前面有奇数个反斜杠,则反斜杠被转义,如果反斜杠前面有偶数个反斜杠,则反斜杠未转义。正则表达式不是该工作的正确工具:)
    • @hvd 好吧,我已经修复了输入的开头,我并不真正关心大量反斜杠 - 这似乎不太可能输入,但谁知道呢。
    猜你喜欢
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多