在Lua中将输入中的双反斜杠替换为单反斜杠

在Lua中将输入中的双反斜杠替换为单反斜杠,lua,escaping,Lua,Escaping,假设我有一个str变量,我给它赋值test\\ttest(在这种情况下,它实际上可以是\\)。我想做的是,用单反斜杠代替双反斜杠 目的很明确:我想输出转义序列(水平选项卡),而现在它只是作为纯文本输出 很明显,我不能使用: str:gsub("\\","\") 因为这会导致语法错误,\“被识别为转义序列。我尝试了所有可能的方法。我也尝试了使用loadstring()(以及嵌套的loadstring()调用),但也失败了 请不要说要做: str:gsub("\\t","\t") 当然,它会起作

假设我有一个
str
变量,我给它赋值
test\\ttest
(在这种情况下,它实际上可以是
\\
)。我想做的是,用单反斜杠代替双反斜杠

目的很明确:我想输出转义序列(水平选项卡),而现在它只是作为纯文本输出

很明显,我不能使用:

str:gsub("\\","\")
因为这会导致语法错误,
\“
被识别为转义序列。我尝试了所有可能的方法。我也尝试了使用loadstring()(以及嵌套的loadstring()调用),但也失败了

请不要说要做:

str:gsub("\\t","\t")

当然,它会起作用,但这不是我需要的。我需要用一个反斜杠替换一个双反斜杠。

我怀疑你被引号弄糊涂了,因为
string.gsub
可以替换反斜杠字符:

C:...> lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio > a="test\\\\ttest" > =a test\\ttest > =a:gsub([[\\]],[[\]]) test\ttest 1 > 如果解析用户提供的文本并希望处理用户提供的文本中的反斜杠转义,那么这样的函数可能会很有用。字符串文本应该已经由编译器处理了

另一个注意事项是,如果您发现自己使用的是部分翻译的字符串,那么实际上您可能会遇到设计不清晰的问题。在解析用户输入之外,实际上需要这样的功能,这表明您的设计可能存在更深层次的问题


函数
unbackslashed
的工作原理是首先将所有已识别的以反斜杠形式后跟单个字符的序列替换为它们的等效数字形式。第二次传递将所有数字形式转换为它们的文字字符。需要两次传递,因为
string.gsub可以理解字符串模式
不支持完全正则表达式解析器支持的替代符号。否则,要匹配的模式可能编写得类似于Perl的
/\\([0-9]{1-3})\\\()/
以及一次性执行的替换\\“。正如您在第二部分中提到的,这不是我所要求的,事实上我不想输出
\t
,而是一个水平制表符。您的
unbackslashed
函数也不是我所要求的。查看OP,我明确地说我不想用
\t
替换
\\t
,而是用“\”替换“\”。但是,我认为没有必要在该函数中使用ASCII码和string.char(),而仅使用类似于
s:gsub(“\\t”,“\t”)
中的ASCII字符就可以了。但这并不是我问题的答案。如果要输出实际的水平制表符,则字符串必须包含该字符,而不是两个字符
\t
。当双字符序列出现在由单引号或双引号构成的字符串文字中时,在编译时就可以理解它。
unbackslashed
函数模拟Lua编译器对字符串文字的处理,并可用于将包含
\t
的字符串转换为包含实际水平制表符的字符串。
function unbackslashed(s)
    local ch = {
        ["\\a"] = '\\007', --'\a' alarm             Ctrl+G BEL
        ["\\b"] = '\\008', --'\b' backspace         Ctrl+H BS
        ["\\f"] = '\\012', --'\f' formfeed          Ctrl+L FF
        ["\\n"] = '\\010', --'\n' newline           Ctrl+J LF
        ["\\r"] = '\\013', --'\r' carriage return   Ctrl+M CR
        ["\\t"] = '\\009', --'\t' horizontal tab    Ctrl+I HT
        ["\\v"] = '\\011', --'\v' vertical tab      Ctrl+K VT
        ["\\\n"] = '\\010',--     newline
        ["\\\\"] = '\\092',--     backslash
        ["\\'"] = '\\039', --     apostrophe
        ['\\"'] = '\\034', --     quote
    }
    return s:gsub("(\\.)", ch)
        :gsub("\\(%d%d?%d?)", function(n)
            return string.char(tonumber(n))
        end)
end