【问题标题】:Expand environment variable inside Perl regex在 Perl 正则表达式中展开环境变量
【发布时间】: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/.../.../ 以避免转义/(因为它不再是语句中的分隔符。您也可以使用$ENV{HOME} 来访问环境变量Perl 而不是使用 shell 中的那个。请注意,根据引用,您可能需要转义 $“由于某种原因,perl 会在单引号和双引号内扩展变量。” - Perl此处没有扩展任何内容,但 shell 会这样做,因为您在 perl 语句周围使用了双引号,即 eval "....shell will expand things here ..."
  • 任何时候你在使用 eval 你可能做错了什么。您不需要使用 eval 将环境变量导入 Perl。它们已经存在,在 %ENV 哈希中。如果你想在正则表达式中转义字符,你可以使用\Q 来引用元字符。如果您添加一个简单的测试用例,这可能是一个非常简单的 Perl 任务。

标签: regex bash perl script


【解决方案1】:

只需将想法组装在 cmets 中,这应该可以达到您的预期:

perl -pi -e 's{$ENV{HOME}/_TV_rips/}{}g' *$videoID.info.json

@ikegami 感谢您的评论!使用 \Q...\E 确实更安全,以防 $HOME 包含 $ 之类的字符。

【讨论】:

  • 这在我的系统上不起作用(perl 5,版本 18)。在@ikegami 的回复中使用 \Q 就可以了。
  • @Kasam。你误会了。这工作正常。 \Q 应该只帮助处理$ENV{HOME} 中的特殊字符,其中不应该有任何特殊字符。如果您依赖\Q,那么您做错了什么(例如使用"...$HOME..." 而不是'...$ENV{HOME}...',而不是使用我们发布的内容。
  • @ikegami 我又试了一次,效果很好。感谢您的提醒。更简单的语法。
【解决方案2】:

所有 RegEx 分隔符当然必须在输入字符串中进行转义。

但正如 Stefen 所说,您可以在 perl 中使用其他分隔符,例如 %, §

特殊字符

  1. #Perl 评论 - 不要使用这个
  2. ?,[], {}, $, ^, . 正则表达式控制字符 - 必须在正则表达式中转义。如果您的字符串中有许多斜杠,这会更容易。

您应该始终写注释以明确您使用不同的分隔符,因为这会使您的正则表达式难以被没有经验的用户阅读。

在这里试用您的正则表达式:https://regex101.com/r/cIWk1o/1

【讨论】:

    【解决方案3】:

    您正在构建以下 Perl 程序:

    s//home/username\/_TV_rips\///g
    

    这是完全错误的。

    您不应该首先尝试从 shell 构建 Perl 代码。有几种方法可以将值传递给 Perl 代码,而不是生成 Perl 代码。由于值在环境中很方便,我们可以使用

    perl -i -pe's/\Q$ENV{HOME}\E\/_TV_rips\///' *"$videoID.info.json"
    

    或者更好

    perl -i -pe's{\Q$ENV{HOME}\E/_TV_rips/}{}' *"$videoID.info.json"
    

    (另请注意缺少eval 以及全局上的固定引用。)

    【讨论】:

    • 太棒了,谢谢!第二个版本的语法更简洁。对于文件内容的扩展正则表达式编辑,您推荐什么工具而不是 perl?
    • @Kasam, 1) 您没有确定排除perl 的原因,因此无法知道还有哪些其他工具不在考虑范围内 2) 工具建议偏离主题跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    相关资源
    最近更新 更多