【问题标题】:Perl Multiline Regex Replacing Capture Group [duplicate]Perl多行正则表达式替换捕获组[重复]
【发布时间】:2017-03-15 05:50:15
【问题描述】:

我正在向 Makefile 添加一行 Perl 代码,该文件在 httpd.conf 中搜索类似以下块的内容,并将 AllowOverride 的“None”替换为“All”。

<Directory "/var/www/html">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride None

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>

我试图从命令行运行的代码如下:

sudo perl -p  -i -e 's/(<Directory "\/var\/www\/html">.*AllowOverride )(None)/\1 All/' httpd.conf

但我无法让它工作。我使用两个捕获组来保持第一个组相同并替换第二个。

非常感谢任何帮助。

编辑:这解决了它

sudo perl -0777 -p -i -e 's/(<Directory \"\/var\/www\/html\">.*?AllowOverride) (None)/\1 All/s' httpd.conf

【问题讨论】:

  • -p 标志默认一次只读取一行。尝试通过添加-0777 一次啜饮超过一行。另见How to replace multiple any-character (including newline) in Perl RegEx?
  • 另外,请确保使用非贪婪的.*?,否则它将一直匹配到最后一个AllowOverride。使用$1,而不是\1 -- 或\K(一种积极的后视)。
  • 这解决了它: sudo perl -0777 -p -i -e 's/(.*?AllowOverride) (无) /\1 All/s' httpd.conf
  • 太棒了。再说一遍:不是\1,而是$1\1 长期以来一直没有用于此目的,虽然它不应该给您带来麻烦用于正则表达式中的其他东西。
  • 有一个模块,Apache::Admin::Config,用于读取和编辑 Apache 配置文件。

标签: regex perl


【解决方案1】:

一般来说,解析和修改任何嵌套的正则表达式会很快变得复杂,容易出错。如果可以,请使用完整的解析器。

幸运的是,有一个用于读取和修改 Apache 配置文件,Apache::Admin::Config。一开始有点奇怪,所以举个例子吧。

#!/usr/bin/env perl

use strict;
use warnings;
use v5.10;

use Apache::Admin::Config;

# Load and parse the config file.
my $config = Apache::Admin::Config->new(shift)
    or die $Apache::Admin::Config::ERROR;

# Find the <Directory "/var/www/html"> section
# NOTE: This is a literal match, /var/www/html is different from "/var/www/html".
my $section = $config->section(
    "Directory",
    -value => q["/var/www/html"]
);

# Find the AllowOverride directive inside that section.
my $directive = $section->directive("AllowOverride");

# Change it to All.
$directive->set_value("All");

# Save your changes.
$config->save;

您一次钻入一层结构。首先找到该部分,然后找到其中的指令。

您可以循环执行此操作。例如,查找所有目录部分...

for my $section ($config->section("Directory")) {
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2020-09-14
    • 2010-11-19
    • 2013-01-31
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多