regex - Perl:匹配引号中包含斜杠的字符串

标签 regex perl

我目前正在编写一个 Perl 脚本来解析配置文件。语法如下

{command parameter1 parameter2}

其中第二个参数是可选的。首先,我只想提取 {} 之间的内容。我正在使用此代码

while (<FILE>) {
    chomp;
    unless ($_ =~ m/^\/\//) {
            $_ =~ /^\{(.*?)\}/s;
            print $1;
}

将进一步评估字符串,而不是 print 命令。我现在的问题是脚本停止处理某些字符串

只要参数两边有引号,脚本就可以工作。这个

{exec sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new}

将返回括号之间的内容,但由于可能有第二个参数,现在很难区分没有引号的参数

其他字符串,例如

{exec "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"}
{exec "/etc/init.d/ssh reload"}

工作完美,包括引号。

但是现在,引号中包含斜杠或加号(也许还有其他)的字符串此时会卡住 perl 脚本:

{exec "chmod +x /root/setSSHTimer.sh"}
{exec "sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new"}

两者都带有引号。当将第一个重写为“chmod 770...”时,它会再次起作用。

有什么想法导致这里出现问题吗?

最佳答案

问题不在于您所显示的代码,该代码只是提取 {...} 之间的所有内容大括号,但在进一步评估代码中。如果您遇到问题,请发布此内容

请注意,您只需使用不同的分隔符和类似 next if m|^//| 的行即可避免在正则表达式中转义斜杠。避免将循环的所有其余部分放在 if 中声明

解析命令行很尴尬 - 因为您必须处理 "..." 中包含的参数。和'...'引号,允许在参数内使用转义引号 - 但可能

这是一个似乎可以正确解析所有示例数据的程序

use strict;
use warnings;

while (<DATA>) {

  next if m|^//| or not /\S/;

  if (/^\{(.*?)\}/) {
    my $command = $1;
    my @fields = $command =~ /'(?:\\'|[^'])*'|"(?:\\"|[^"])*"|\S+/g;
    print join(' ', map "[$_]", @fields), "\n";
  }
}

__DATA__
{exec sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new'}
{exec "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"}
{exec "/etc/init.d/ssh reload"}
{exec "chmod +x /root/setSSHTimer.sh"}
{exec "sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new"}

输出

[exec] [sed] ['s/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new']
[exec] ["cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"]
[exec] ["/etc/init.d/ssh reload"]
[exec] ["chmod +x /root/setSSHTimer.sh"]
[exec] ["sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new"]

更新

此配置格式至少应按行分割,以便可以删除引号和转义符,例如

exec
sed
s/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/ /etc/ssh/sshd_config > /etc/ssh/sshd_config.new

exec
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

exec
/etc/init.d/ssh reload

exec
chmod +x /root/setSSHTimer.sh

exec
sed
s/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new

正确输入和解析都很容易(尽管我确信你的最终 sed 示例是错误的!)

关于regex - Perl:匹配引号中包含斜杠的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12138508/

相关文章:

string - 为什么这些值有时未定义?

python - 使用 Python 进行多个正则表达式的列表理解

regex - Sed:如何将反向引用转换为变量名?

perl - 是在这里我要使用的还是弹出的?

mysql - 为什么 Apache 提示我的 mod_perl 程序 "disconnect invalidates 1 active statement handle"?

perl - 为什么 DBD::CSV 提示 "Loose unescaped quote"?

javascript - 从字符串中删除多余的 <br>

regex - 如何在Perl中遍历正则表达式匹配变量?

Java 正则表达式 - 匹配模式的第一次出现

Perl 一行 if 语句