【问题标题】:Escaping wildcard file paths perl转义通配符文件路径 perl
【发布时间】:2012-10-26 06:53:30
【问题描述】:

我有一个文件数组:

my @plistFiles = glob('Logs/*/*.plist');

我需要转义,它将包含 '(' 和 ')' 以及通常的空格。

这是@plistFiles 将返回的文件路径之一:

Logs/Run 1 (13)/Automation Results.plist

我目前有此代码用于转义文件路径中的空格,我将其传递给 OSX 终端中的命令:

$plistFile =~ s/\ /\\\ /g;

那么我怎样才能编辑这个正则表达式来转义(和)?

这对于转义 ( 和 ) 是否正确?:

$plistFile =~ s/\(\d)/\\\(\d\\\)/g;

【问题讨论】:

  • 你想用什么来代替“和”?
  • @sputnick 我不想“替换”但只是转义字符
  • 您究竟想“逃避”什么?出于什么目的?所有(),还是只有数字附近的那些?空格也?其他元字符?
  • @pavel 只是 (,) 围绕数字和所有空格,我在终端中使用每个文件路径,所以我需要转义这些字符。没有其他元字符。
  • 你没有指定要转义的目的,那我们怎么知道需要转义什么或者如何转义呢?

标签: regex perl escaping


【解决方案1】:

我不明白为什么打电话给quotemeta 是不够的。是的,它也会避开斜线和圆点,但这没关系。

不过,只转义空格和括号也很简单。

这个程序展示了这两种技术

use strict;
use warnings;

use feature 'say';

my $path = 'Logs/Run 1 (13)/Automation Results.plist';
my $escaped = quotemeta $path;
say $escaped;

$escaped = $path =~ s/([\s()])/\\$1/gr;
say $escaped;

输出

Logs\/Run\ 1\ \(13\)\/Automation\ Results\.plist

Logs/Run\ 1\ \(13\)/Automation\ Results.plist

【讨论】:

  • 我正在学习perl,不知道quotemeta,但我对正则表达式有一些经验,所以我使用了这种方法
【解决方案2】:

使用正则表达式,您可以添加转义斜线

s/[() ]/\\$&/g;

this demo

s/(?=[() ])/\\/g;

this demo

【讨论】:

    【解决方案3】:

    您会发现使用 {} 来分隔您的正则表达式更容易。节省一些\眼睛晃动。

    #!/usr/bin/perl
    use strict;
    use warnings;
    use utf8;
    use 5.10.0;
    use Data::Dumper;
    
    my $to_match = "( this dreadful ) filename";
    $to_match =~ s{([\(\)])}{\\$1}g;
    say $to_match;
    

    这样做:

    $ perl x.pl
    \( this dreadful \) filename
    

    如果你需要转义空格以及 ()s 那么

    $to_match =~ s{([\(\s\)])}{\\$1}g;
    

    【讨论】:

    • 你的第一段对我来说没有意义。使用 s{}{} 而不是 s/// 只会在模式或替换包含 / 时保存反斜杠 - 这里不是这种情况。
    【解决方案4】:

    转换例如(13)\(13\),你可以写:

    $plistFile =~ s/ /\\ /g;
    $plistFile =~ s/\((\d+)\)/\\($1\\)/g;
    

    但我认为你最好只转义()所有 个实例,无论它们是否围绕数字:

    $plistFile =~ s/([ ()])/\\$1/g;
    

    【讨论】:

    • 我只是想理解你的最后一行代码,如果我错了,请纠正我,但这意味着:() 的任何实例都将替换为\ \(\)
    • @user1160022:这意味着任何空格、左括号或右括号都将替换为反斜杠加上自身。 (它对character-class 使用[...] 表示法,对capture-group 使用(...) 表示法,并使用特殊变量$1 来检索第一个捕获组的内容。)
    • @Ωmega:没有必要,但是使用$& 会对整个程序中其他任何地方的所有正则表达式匹配造成性能损失。这种惩罚通常不值得失眠,但在 StackOverflow 答案的上下文中,当我什至不知道程序还在做什么时,我宁愿避免它。另外,我认为$1$& 稍微清晰一点,因为(几乎?)所有类似Perl 的正则表达式引擎都采用了$1,但几个主要的还没有采用$&。 (顺便说一句,挑剔:正确地说,如果我在模式中使用了类似 \1 的东西,那么“反向引用”就是这样。)
    猜你喜欢
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 2014-01-16
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多