正则表达式重命名/修改重复行

时间:2016-08-01 07:59:15

标签: regex replace duplicates rename

我正在寻找一个UNIX / Perl / PHP样式的正则表达式来执行以下文本字符串列表:

  • 搜索“#”字符开头的第一行
  • 使用搜索字符串的更多次出现修改所有字符串,但在开头没有“#”,以便行也以“#”开头。这些行可能有尾随文本(但不一定是)。

必须在一条路上完成。

E.g:

some line
# some string
some line
some line
some line
some string some other string
some line
some line
some string
some line
some line
some line
some string some trailing text
some line

Regex101

所以我要求的是一个与# some string行匹配的正则表达式,然后在以#开头的其他行的开头添加some string。匹配和修改的行是

  • some string some other string - > # some string some other string
  • some string - > # some string
  • some string some trailing text - > # some string some trailing text

我考虑过像^(#?[^\r\n]+$)[\s\S]*(^\1[^\r\n]*$)+这样的事情来匹配所有这些事件,但是我需要将其拆分以替换每个事件......

感谢。

3 个答案:

答案 0 :(得分:1)

尝试将其写为单个正则表达式听起来像是不可维护代码的配方。我这样写:

my $prefix;
while (<>) {
  # If we find a line that starts with #, then set $prefix
  if (/^# (.*)/) {
    $prefix = $1;
  }

  # If $prefix is defined and we find a line that starts with $prefix,
  # then prepend '#'
  if (defined $prefix and /^$prefix/) {
    $_ = "$prefix $_";
  }

  print;
}

答案 1 :(得分:0)

背后的变量看起来很棒。
但大多数正则表达式引擎都不支持这一点。只有固定的外观。

但是,如果您可以反转该字符串列表 那么你可能仍然可以在反向文本上使用正向前瞻。并在更换后将文本反转。

一个非常简单的例子。

我们从文本开始:

z
# a
a y
a
x

现在我们撤消文字:

x
a
y a
a #
z

现在我们替换所有(全局,多线)
(\w+$)(?=[\s\S]+\1 ?#)
\0 #

我们得到:

x
a #
y a #
a #
z

现在反转结果:

z
# a
# a y
# a
x

答案 2 :(得分:0)

查找:

(?-s)(?:.*\R)*?\K.*(some string).*(?s)(\R.*)\1

替换为:

\1\2 some other string