【问题标题】:Regex works in terminal but not in Perl script正则表达式在终端中有效,但在 Perl 脚本中无效
【发布时间】:2020-10-27 07:05:07
【问题描述】:

这与this question有关

以反斜杠字符结尾的所有行的组合完成。以下 Perl 命令在终端中有效,但在 Perl 脚本中无效:

perl -i -p -e 's/\\\n//' input_file

在 Perl 脚本中,我是这样设置的,但它不起作用:

`perl -i -p -e 's/\\\n//' $input_file_path_variable`;

**更新了文件内容和使用的代码

输入文件内容如下:

foo bar \
bash \
baz
dude \
happy

想要的输出内容:

foo bar bash baz
dude happy

当前脚本:

#!/usr/bin/env perl 

use Getopt::Long;
use FindBin;
use File::Path;
use File::Copy;
use DirHandle;
use FileHandle;
use File::Basename;
use Env;
use File::Slurp;

my $dummy_file = "/wdir/dummy.txt";
my $file_content = read_file($dummy_file);
print "$file_content\n";
print "==============================================\n"

my $ttest = $file_content =~ s/\\\n//;
print "$ttest\n";

电流输出

foo bar \
bash \
baz
dude \
happy
==============================================
1

【问题讨论】:

  • 反引号充当双引号字符串文字,\\ 在双引号字符串文字中变为 \ 。 /// 另外,你有一个代码注入错误。这不是创建 shell 命令的正确方法。请参阅字符串::ShellQuote。 /// 最后,为什么要对一个不向 STDOUT 产生输出的程序使用反引号?您可以通过使用 system 的多参数形式来避免使用 String::ShellQuote。
  • @tobyink 是的,我可以知道正确的方法吗?我尝试将整个文件读入一个变量并应用 Oliver 的答案,但无法获得所需的输出。
  • 向我们展示您的代码、您正在使用的输入,以及它如何不工作的演示。
  • @TLP 我不好,我已经用所用的输入更新了问题。你的假设是对的,你的回答解决了我的问题。谢谢。
  • @tobyink 指出在另一个 Perl 脚本的反引号中不使用 Perl 单行,我不知道这是一个坏主意。认为这是做我想做的事情并更改输入文件内容的最快方法。

标签: regex perl text


【解决方案1】:

我想我意识到你的问题是什么。您需要多次进行替换匹配。

您正在使用这种单线:

perl -i -p -e 's/\\\n//' input_file

这将替换以逐行模式读取的文件中的反斜杠和换行每行一次。现在你正试图在另一个程序中实现它,你正在将整个文件放入一个变量中,正如你在另一个答案的评论中提到的那样:

我尝试将整个文件读入一个变量并应用您的解决方案,但对我不起作用:我的 $file_content = read_file($input_file_path_variable) 然后 $file_content =~ s/\\n//;

这只会替换一次。文件中的第一个匹配项。您需要添加修饰符 /g 以使匹配尽可能多地成为全局:

$file_content =~ s/\\\n//g;

我不确定您是如何使用您的代码的,因为您没有向我们展示。这使得回答简单的问题变得困难。但如果我的假设是正确的,这将解决您的问题。

【讨论】:

    【解决方案2】:

    我认为自最初提出问题以来,您至少更改了一次代码/方法,但根据您当前的代码,您的问题是这一行:

    my $ttest = $file_content =~ s/\\\n//;
    

    首先,s/// 运算符需要在末尾添加一个g,以便进行全局搜索和替换,而不是在第一次替换后停止。

    其次,$file_content =~ s/\\\n// 不返回最终字符串;它就地修改字符串。 (所以它正在改变 $file_content。)在最近的 Perl 版本中,您可以在末尾添加一个 r 修饰符以使其返回修改后的字符串。

    所以这些都适合你:

    my $ttest = ( $file_content =~ s/\\\n//gr );
    

    或者:

    ( my $ttest = $file_content ) =~ s/\\\n//g;
    

    产生你想要的输出的完整脚本:

    #!/usr/bin/env perl 
    
    use strict;
    use warnings;
    use File::Slurp;
    
    my $file_content = read_file('/tmp/dummy.txt');
    
    (my $ttest = $file_content) =~ s/\\\n//g;
    
    print "$file_content\n";
    print "==============================================\n";
    print "$ttest\n";
    

    【讨论】:

      【解决方案3】:

      在 Perl 中你应该这样写:

      $input_file_variable =~ s/\\\n//;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 2012-04-02
        • 2016-09-19
        相关资源
        最近更新 更多