[英]Regex - matching a multiline block by noting the absence of a string and then inserting it
多么令人滿意的一個主題。
所以本質上我有一個模式,我需要在一個基於該模式缺少某些東西的文件中找到。
例如,我有:
Huge amounts of preceding code...
someHeader
{
someInfo = "blah blah blah";
}
Huge amounts of ending code...
我需要做的是讓它看起來像這樣:
someHeader
{
someDescription = "Excellent information found here!";
someInfo = "blah blah blah";
}
Huge amounts of ending code...
底線:我需要找到沒有“someDescription”的“someHeader”塊的所有實例並插入它。 “someInfo”也不會一直存在,所以我真的需要找到"someheader\\r\\t\\t{\\r\\t\\t\\t!someDescription"
並將其替換為"someheader\\r\\t\\t{\\r\\t\\t\\tsomeDescription = "Excellent information found here!";\\r"
考慮算法:
如果該行匹配“someHeader”:
創建一個新緩沖區,但當前行進入它
繼續讀取更多行到緩沖區,直到該行匹配“}”
如果緩沖區不包含“someDescription”,則插入它
打印緩沖區
否則打印線
這是一個基本的Perl實現:
#!/usr/bin/perl -n
if (/^someHeader/) {
$buf = $_;
while (($line = <>) !~ /}/) {
$buf .= $line;
}
$buf .= $line;
if ($buf !~ /someDescr/) {
$buf =~ s/{/{\n someDescription = "Excellent";/;
}
print $buf;
} else {
print;
}
用它作為:
perl parser.pl < sample.cc
這段代碼不會贏得選美比賽,但它應該有效。 您可能需要使正則表達式更嚴格以避免誤報,當然您還需要其他代碼來實際更新源文件。 祝好運。
我喜歡Joe Z的解析器建議,但也許以下 - 使用負面預測 - 可能會提供一些幫助:
use strict;
use warnings;
my $string = do { local $/; <DATA> };
my $replacement = qq{someDescription = "Excellent information found here!";\n\t\t\t};
$string =~ s/(?:someHeader\n\t\t{\n\t\t\t)\K(?!someDescription)/$replacement/gs;
print $string;
__DATA__
someHeader
{
someDescription = "Excellent information found here!";
someInfo1 = "blah blah blah";
}
someHeader
{
someInfo2 = "blah blah blah";
}
輸出:
someHeader
{
someDescription = "Excellent information found here!";
someInfo1 = "blah blah blah";
}
someHeader
{
someDescription = "Excellent information found here!";
someInfo2 = "blah blah blah";
}
這可能適合你(GNU sed):
sed '/someHeader/{:a;$!N;/}/!ba;/someDescriptiom/!s/\(\n\s\+\){/&\1\tsomeDescription = "Excellent information found here!";/}' file
在遇到someHeader
讀取更多行,直到找到}
。 搜索someDescription
的結果,如果沒有找到,請在第一個{
。后面附加someDescription bla bla ...
NB嵌套括號和所有賭注都關閉!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.