在 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 正则表达式中展开环境变量的主要内容,如果未能解决你的问题,请参考以下文章

Perl正则表达式引用

Perl正则表达式选项存储在变量中[重复]

Perl正则表达式匹配多行文件与匹配变量如何处理换行

在perl中使用变量作为正则表达式修饰符[重复]

perl学习正则表达式处理文本

Perl 中的正则表达式组:如何从正则表达式组中捕获与字符串中出现的未知数量/多个/变量匹配的元素到数组中?