我一直在尝试调用一个包含来自windows环境variables的多字节字符的参数,但是还没有find可行的解决scheme。 这是我至今能够deBUGging的东西。
为了简单起见,假定我有一个名为“Seán”的目录,我试图用它作为exec的一个参数。 如果我只是打电话
exec 'script',"Seu00E1n".encode("IBM437")
被执行的脚本找不到该文件,因为arg被调整为重音字符丢失。 如果我按照下面的方法进行 *** 作,但是这样做是不好的做法,因为在进入shell之前,arg应该被转义。
exec "script #{"Seu00E1n".encode("IBM437")}"
所以我的想法是,我只是使用shellescape来保护exec的使用。
java控制台输出的默认字符编码
在C / C ++中检测string的编码
R,windows和外语字符
在哪个windows版本中,windows ANSI Western(cp 1252)首次出现?
在linux中将网页从UTF-8转换为ISO-8859-1
require 'shellwords' exec "script #{"Seu00E1n".encode("IBM437").shellescape}"
但问题是,它逃脱了特殊的性格,所以它看起来像下面这样 – “Se án”。 我想清楚这是在发生什么,它是从这个正则Expression式来的 。
str.gsub!(/([^A-Za-z0-9_-.,:/@n])/,"\\\1")
乍看之下,似乎是逃避了已知的一组好的shell字符中的字符。 不幸的是,这套不包括特殊字符,所以我遇到了问题。
我正在寻找的是一个正则Expression式,它会执行shell转义,不会混淆特殊字符,以便在将它们传递给exec之前可以将这些参数转义。
如何检测UTF8文本的等效windows代码页
将未知文件编码批量转换为UTF-8
我如何base64编码在linux上的string,使其匹配窗口“Unicode.GetBytes.ToBase64String”?
换行从linux到windows的新行字符丢失
在windows上,我无法使用cmd在我的数据库中看到utf8mb4字符
正则表达式/([^A-Za-z0-9_-.,:/@n])/只处理ASCII字母和数字,不是所有的Unicode字母。 [^...]是否定字符类 ,它匹配除了在类中指定的字符以外的所有字符。 所以,所有的Я , Ц , Ą都被删除,因为它们与[A-Za-z]不匹配。
你需要的是添加速记类来排除所有的Unicode字母和数字 。 为了使它更安全,我们可以添加一个变音符号类以便保留变音符号:
str.gsub(/([^p{L}p{M}p{N}_.,:/@n-])/,"\\\1")
在这里, p{L}匹配所有Unicode基本字母, p{M}匹配所有的变音符号, p{N}匹配任何Unicode数字。
请注意,连字符在放置在字符类的开始/结尾处(或在有效范围或简写字符类之后)时无需转义。
TL; DR
转义字符
码
String.class_eval do def escapeshell() # Escape shell special characters self.gsub!(/[#-&(-*;<>?[-^`{-~u00FF]/,'\\') # Escape unbalanced quotes (single and double quotes) self.gsub!(/(["'])(?:([^"']*(?:(?!1)["'][^"']*)*)1)?/) do if $2.nil? '\' + $1 else # and escape quotes insIDe (eg "x'x" or 'y"y') qt = $1 qt + $2.gsub(/["']/,'\\') + qt end end self end end # Test it str = "(dir *.txt & dir "\some dir\Sèu00E1ñ*.rb") | sort /R >Filé.txt 2>&1" puts 'String:' puts str puts "nescaped:" puts str.escapeshell
产量
String: (dir *.txt & dir "some dirsèáñ*.rb") | sort /R >Filé.txt 2>&1 Escaped: (dir *.txt & dir "\some dir\Sèáñ*.rb") | sort /R >Filé.txt 2>&1
IDeone演示
描述
元字符
考虑到应该转义的shell元字符:
# & % ; ` | * ? ~ < > ^ ( ) [ ] { } $ u00FF
我们可以在字符类中包含每个字符:
[#&%;`|*?~<>^()[]{}$\u00FF]
这与以下内容完全相同:
/[#-&(-*;<>?[-^`{-~u00FF]/
然后,我们使用gsub!()在类中的任何字符之前加上一个反斜杠:
str.gsub!(/[#-&(-*;<>?[-^`{-~u00FF]/,'\\')
行情
只有不平衡的引号需要逃脱。 这对保存命令的参数非常重要。 用下面的表达式我们匹配平衡的引号:
/(["'])[^"']*(?:(?!1)["'][^"']*)*)1/
以及不平衡,使最后一部分可选
/(["'])(?:[^"']*(?:(?!1)["'][^"']*)*)1)?/
但是我们也需要在另一对里面逃避报价。 这是双引号内的单引号,反之亦然。 所以我们将嵌套另一个gsub()来替换引号( $2 )中匹配的文本:
str.gsub!(/(["'])(?:([^"']*(?:(?!1)["'][^"']*)*)1)?/) do if $2.nil? '\' + $1 else qt = $1 qt + $2.gsub(/["']/,'\\') + qt end end
总结以上是内存溢出为你收集整理的我怎样才能让rubyShellWords.shellescape工作与多字节字符?全部内容,希望文章能够帮你解决我怎样才能让rubyShellWords.shellescape工作与多字节字符?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)