gpt4 book ai didi

ruby - 如何使 ruby​​ ShellWords.shellescape 使用多字节字符?

转载 作者:可可西里 更新时间:2023-11-01 13:27:03 30 4
gpt4 key购买 nike

我一直在尝试使用包含来自 Windows 环境变量的多字节字符的参数调用 exec,但尚未找到可行的解决方案。到目前为止,这是我能够调试的内容。

为简单起见,假设我有一个名为“Seán”的目录,我试图将其用作 exec 的参数。如果我只是打电话

exec 'script', "Se\u00E1n".encode("IBM437") 

执行的脚本无法找到该文件,因为 arg 以丢失重音字符的方式进行了调整。如果我执行以下操作,它会起作用,但这是不好的做法,因为 arg 应该在进入 shell 之前进行转义。

exec "script #{"Se\u00E1n".encode("IBM437")}"

所以我的想法是我会使用 shellescape保护 exec 的使用。

require 'shellwords'
exec "script #{"Se\u00E1n".encode("IBM437").shellescape}"

但问题是它对特殊字符进行了转义,因此它看起来像下面这样 - "Se\án"。我弄清楚这是在哪里发生的,它来自这个 regular expression .

str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1")

乍一看似乎转义字符不在已知的良好 shell 字符集中。不幸的是,这个集合不包含特殊字符,所以我遇到了问题。

我正在寻找的是一个正则表达式,它可以进行 shell 转义,不会弄乱特殊字符,这样我就可以在将这些 args 传递给 exec 之前对其进行转义。

最佳答案

正则表达式 /([^A-Za-z0-9_\-.,:\/@\n])/ 只处理 ASCII 字母和数字,而不是所有 Unicode 字母。 [^...]negated character class匹配除类中指定的字符之外的所有字符。因此,所有 ЯЦĄ 都与该表达式一起删除,因为它们与 [A-Za-z] 不匹配

您需要添加速记类以排除所有 Unicode 字母和数字。为了让它更安全,我们可以添加一个变音符号类来保留变音符号:

str.gsub(/([^\p{L}\p{M}\p{N}_.,:\/@\n-])/, "\\\\\\1")

这里,\p{L} 匹配所有 Unicode 基本字母,\p{M} 匹配所有变音符号,\p{N} code> 匹配任何 Unicode 数字。

请注意,当连字符位于字符类的开头/结尾(或在有效范围或速记字符类之后)时,不需要转义。

关于ruby - 如何使 ruby​​ ShellWords.shellescape 使用多字节字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33905127/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com