正则表达式 - 查找行中的字符串但替换同一行中的另一个字符串
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;
}
我在 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;
}