我需要从完整的POSIX路径(从根开始)创建一个字符串,以便可以 直接将其粘贴到bash
之类的Unix shell中,例如Terminal.app
中,而无需在路径两边加上引号。
(我实际上并没有将字符串传递给shell,而是需要将其传递给另一个程序。该程序期望将路径拖放到{{1 }}。)
为此,我需要至少在字符串中转义任何空格,方法是在它们前面加上反斜杠。还有一些其他字符。
例如,此路径:
Terminal.app
将按照以下说明进行转义:
/directory/-as"<>' *+
执行该转换的安全算法是什么?我可以逃避每个角色,但这太过分了。
似乎没有框架函数可以执行此操作,因此我需要用字符串操作进行替换。
为保守起见(对于最流行的外壳),同时还避免了明显的不必要的转义,应转义哪些字符集?
答案 0 :(得分:0)
最好将整个内容用单引号引起来,而不是在单个字符上加上反斜杠;那么您唯一需要转义的字符就是字符串中的单引号。
作为示例提供的Python standard library's implementation可以很容易地以仅具有基本基元的任何其他语言重新实现,其内容如下:
def quote(s):
"""Return a shell-escaped version of the string *s*."""
if not s:
return "''"
if _find_unsafe(s) is None:
return s
# use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'"
也就是说,一般算法如下:
''
(一对文字单引号)。'
之前添加,发出输入字符串,并用文字字符串'
替换所有'"'"'
,然后附加最后的'
。就是这样。您不需要转义反斜杠(它们在单引号内是字面量),换行符(同样)或其他任何东西。
答案 1 :(得分:0)
作为记录,Terminal.app
在将文件名放入其窗口时转义了以下非控制ASCII字符:
空格
!“ ##%&'()*,:; <=>?[]`{|}〜
这些都无法逃脱:
控制代码(00-1F和7F)
字母数字
+-。@ ^ _
这是执行替换的代码:
NSString* shellPathFromPOSIXPath (NSString *path)
{
static NSRegularExpression *regex = nil;
if (!regex) {
NSString *pattern =
@"([ !\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\,\\:\\;\\<\\=\\>\\?\\[\\]\\`\\{\\|\\}\\~])";
regex =
[NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
}
NSString *result =
[regex stringByReplacingMatchesInString:path
options:0
range:NSMakeRange(0, path.length)
withTemplate:@"\\\\$1"];
return result;
}