在 Perl 正则表达式中展开环境变量
Posted
技术标签:
【中文标题】在 Perl 正则表达式中展开环境变量【英文标题】:Expand environment variable inside Perl regex 【发布时间】:2021-12-15 17:08:14 【问题描述】:我在使用简短的 bash 脚本时遇到了问题。似乎所有正斜杠都需要转义。如何在 perl 读取扩展(环境)变量中的必需字符之前对其进行转义?或者其他 perl 能理解的方法。
这是我正在尝试做的,但这将无法正常工作。
eval "perl -pi -e 's/$HOME\/_TV_rips\///g'" '*$videoID.info.json'
这是videoID=$1
的较长脚本的一部分。 (并且由于某种原因,perl 扩展了单引号和双引号内的变量。)
这个在扩展环境变量$USER
中没有正斜杠的简单解决方法有效。但我不想硬编码/Users/
:
eval "perl -pi -e 's/\/Users\/$USER\/_TV_rips\///g'" '*$videoID.info.json'
这可能可以通过更好的方式来解决,获取文件或其他内容的主目录。目标是删除 youtube-dl 的 json 数据中的文件夹名称。 我使用 perl 只是因为它可以处理扩展的正则表达式。但是 perl 不是必需的。欢迎任何更好的 macOS 上扩展正则表达式的替代品。
【问题讨论】:
XY 问题是询问您尝试的解决方案,而不是您的实际问题。 并非如此。我正在描述我目前遇到的问题,并在最后一段中描述了我的总体目标。并且还说我也对其他方法持开放态度,但也很好奇 perl 出了什么问题并解决了这个问题 - 即使有另一个更好的解决方案我可能会受到 in 答案的启发。 我不明白你为什么要在这里使用 eval 您可以使用s......
代替s/.../.../
以避免转义/
(因为它不再是语句中的分隔符。您也可以使用$ENVHOME
来访问环境变量Perl 而不是使用 shell 中的那个。请注意,根据引用,您可能需要转义 $
。“由于某种原因,perl 会在单引号和双引号内扩展变量。” - Perl此处没有扩展任何内容,但 shell 会这样做,因为您在 perl 语句周围使用了双引号,即 eval "....shell will expand things here ..."
任何时候你在使用 eval 你可能做错了什么。您不需要使用 eval 将环境变量导入 Perl。它们已经存在,在 %ENV
哈希中。如果你想在正则表达式中转义字符,你可以使用\Q
来引用元字符。如果您添加一个简单的测试用例,这可能是一个非常简单的 Perl 任务。
【参考方案1】:
只需将想法组装在 cmets 中,这应该可以达到您的预期:
perl -pi -e 's$ENVHOME/_TV_rips/g' *$videoID.info.json
@ikegami 感谢您的评论!使用 \Q...\E 确实更安全,以防 $HOME 包含 $ 之类的字符。
【讨论】:
这在我的系统上不起作用(perl 5,版本 18)。在@ikegami 的回复中使用 \Q 就可以了。 @Kasam。你误会了。这工作正常。\Q
应该只帮助处理$ENVHOME
中的特殊字符,其中不应该有任何特殊字符。如果您依赖\Q
,那么您做错了什么(例如使用"...$HOME..."
而不是'...$ENVHOME...'
,而不是使用我们发布的内容。
@ikegami 我又试了一次,效果很好。感谢您的提醒。更简单的语法。【参考方案2】:
所有 RegEx 分隔符当然必须在输入字符串中进行转义。
但正如 Stefen 所说,您可以在 perl 中使用其他分隔符,例如 %, §
。
特殊字符
#
Perl 评论 - 不要使用这个
?,[], , $, ^, .
正则表达式控制字符 - 必须在正则表达式中转义。如果您的字符串中有许多斜杠,这会更容易。
您应该始终写注释以明确您使用不同的分隔符,因为这会使您的正则表达式难以被没有经验的用户阅读。
在这里试用您的正则表达式:https://regex101.com/r/cIWk1o/1
【讨论】:
【参考方案3】:您正在构建以下 Perl 程序:
s//home/username\/_TV_rips\///g
这是完全错误的。
您不应该首先尝试从 shell 构建 Perl 代码。有几种方法可以将值传递给 Perl 代码,而不是生成 Perl 代码。由于值在环境中很方便,我们可以使用
perl -i -pe's/\Q$ENVHOME\E\/_TV_rips\///' *"$videoID.info.json"
或者更好
perl -i -pe's\Q$ENVHOME\E/_TV_rips/' *"$videoID.info.json"
(另请注意缺少eval
以及全局上的固定引用。)
【讨论】:
太棒了,谢谢!第二个版本的语法更简洁。对于文件内容的扩展正则表达式编辑,您推荐什么工具而不是 perl? @Kasam, 1) 您没有确定排除perl
的原因,因此无法知道还有哪些其他工具不在考虑范围内 2) 工具建议偏离主题跨度>
以上是关于在 Perl 正则表达式中展开环境变量的主要内容,如果未能解决你的问题,请参考以下文章