转义未转义的正斜杠

转义未转义的正斜杠

我有包含转义和未转义正斜杠的字符串。

我正在寻找 sed 替代品来逃避只有未转义的斜杠,但似乎不支持负向后查找。

例子:

input: "https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"

desired output: "https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com"

答案1

sed用途POSIX 基本正则表达式默认情况下,它不包括通常在 Perl 兼容的正则表达式语言中找到的先行断言和其他零宽度断言。

相反,只需取消转义转义的斜杠,然后转义修改后的字符串中的所有斜杠:

sed -e 's@\\/@/@g' -e 's@/@\\/@g'

这首先将所有实例更改为\//然后全部/更改为\/。这@是替换命令的替代分隔符,以避免牙签倾斜综合症(您几乎可以使用任何其他字符)。

例子:

$ echo '"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"' | sed -e 's@\\/@/@g' -e 's@/@\\/@g'
"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com"

如果文本行存储在 shell 中的字符串中bash,您可以在那里执行类似的操作:

$ string='"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"'
$ string=${string//\\\///}   # leaning toothpick warning!
$ string=${string//\//\\/}
$ printf '%s\n' "$string"
"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com"

上面使用变量替换将in${variable//pattern/replacement}的所有匹配项替换为。pattern$variablereplacement

答案2

在 Perl 中,你可以使用lookbehinds:

$ input="https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"

$ printf '%s\n' "$input" | perl -pe 's|(?<!\\)/|\\/|g'
https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com

答案3

这应该可以解决问题

sed 's:\\\?/:\\/:g'

将任何带有零个或前面一个反斜杠的斜杠替换为转义斜杠。

答案4

sed 没有后向断言,但我们可以模拟它们。此处显示的是扩展正则表达式模式下的 GNU sed (-E)

sed -E '
  :a
  s:(^|[^\])(([\][\])*)[/]:\1\2\\/:
  t a
' file

在看到非反斜杠或到达行首之前,我们确保 / 左侧有偶数个反斜杠(0 是偶数)。

相关内容