正则表达式 - 查找行中的字符串但替换同一行中的另一个字符串

Regex - Find string in line but replace another string in the same line

我在 Perl 正则表达式语法中查找和替换时遇到问题:

我有以下几行:

FILEGROUP [PAYMENT_MGMT](NAME = [PAYMENT_MGMT], FILENAME = '$(DefaultDataPath)$(DatabaseName)_PAYMENT_MGMT.ndf', FILEGROWTH = 102400 KB)

LOG ON (NAME = [SQL_log], FILENAME = '$(DefaultLogPath)$(DatabaseName)_log.ldf', SIZE = 5012 KB, MAXSIZE = 2097152 MB, FILEGROWTH = 102400 MB) COLLATE Slovenian_CI_AS

所以我必须找到字符串 SQL_log 但仅将 SIZE = 替换为 SIZE = 1024

我如何使用正则表达式 PCRE 实现此目的?

捕获目标之前的所有内容并将其放回替换中:

$x =~ s/^(.*?SQL_log.*?SIZE = )\d+/1024/;

测试代码:

$x = "foo SQL_log bar SIZE = 5012 baz";
$x =~ s/^(.*?SQL_log.*?SIZE = )\d+/1024/;
print $x;

输出:

foo SQL_log bar SIZE = 1024 baz

我找到答案了!

搜索:

(IGP_log.*?\bSIZE\b\s=)(\s[0-9]+) 

替换:

 1024

 1024

如果您保证在同一行上不会有超过一个 SQL_log 记录,或者 SQL_log LOG 记录总是 "NAME =" AND "SIZE =" 按照这个顺序,以下应该是一个安全的解决方案:

s/\b(NAME\s*=\s*\[SQL_log\].+?\bSIZE\s*=\s*)[^,)]*/1024 KB/

如果您不能保证 "NAME =" 和 "SIZE =" 将始终按该顺序排列,但您可以保证每行永远不会超过一个,那么您还需要:

s/\b(SIZE\s*=\s*)[^,]*(.+?\bNAME\s*=\s*\[SQL_log\])/1024 KB/

再一次,所有的解决方案都将所有内容都塞进了一个正则表达式中。我不明白为什么人们这样做;语言的任何其他部分都不会发生这种情况

这样写就清楚多了

if ( /NAME \s* = \s* \[SQL_log\]/x ) {

    s/SIZE \s* = \s* \K \d+/1024/x;

}