【问题标题】:Regex combine lines正则表达式结合线
【发布时间】:2020-05-03 02:51:51
【问题描述】:

给定以下字符串

45op0
tr ico
JJB Be
tyuh
113-4997
202076
acure
sala mandra

我正在寻找以下结果:

45op0;113-4997
tr ico;202076
JJB Be;acure
tyuh;sala mandra

基本上将底部的 4 行与顶部的 4 行按原始顺序组合在一个 ; 分隔列表中。

这是我目前的正则表达式:

^((?:[^\r*\n]*[\r*\n]){4})([\s\S]*)

替换为:

$1;$2

如图所示demo

如您所见,这并没有给出预期的结果。

任何帮助将不胜感激。

【问题讨论】:

  • 这几乎肯定会在你的应用层更容易做到。
  • 你使用什么语言?

标签: regex combinations pcre


【解决方案1】:

你可以使用正则表达式

^(.+)\r?\n(?=(?:.*\r?\n){3}(.+))

PCRE demo

对于给出的示例,有四个匹配项:45op0tr icoJJB Betyuh。每场比赛有两个捕获组。第一个捕获组包含匹配本身。对于第一个匹配项 (45op0),捕获组 2 包含 113-4997,它在正向前瞻中被捕获。然后可以将两个捕获组的内容连接起来,用分号分隔,返回45op0;113-4997

同样,对于第二个匹配捕获组 2 包含 202076,依此类推。

当到达113-4997 行时,它被保存在 cap grp 1 中,接下来的三行被消耗,然后正则表达式失败,因为后面没有非空行。对于下一行,正则表达式失败,因为它无法跳过三行。

PCRE 正则表达式引擎执行以下操作。

^(.+)          match a line with 1+ chars, excl. line terminators,
               in cap grp 1 
\r?\n          match the newline and possible carriage return
(?=            begin a positive lookahead
  (?:.*\r?\n)  match an entire line in a non-cap group          
  {3}          execute the non-cap group 3 times (skip 3 lines)
  (.+)         match a line with 1+ chars, excl. line terminators,
               in cap grp 2
)              end positive lookahead

【讨论】:

  • 这与我想出的类似,但无论如何我都找不到完全摆脱最后 4 行的方法(我能做的最好的是将它们减少到 ;)。这就是为什么我建议它应该在应用层完成。
  • @Nick,代码肯定需要对正则表达式匹配做任何事情,但是 OP 没有给我们正在使用的语言,所以这是我能做到的。如果变量strr 分别保存字符串和我的正则表达式,在Ruby 中可以写成str.gsub(r).map { |_,a| m = Regexp.last_match; "%s;%s" % [m[1],m[2]] } #=> ["45op0;113-4997", "tr ico;202076", "JJB Be;acure", "tyuh;sala mandra"]。我希望在任何其他通用语言中都会有类似的东西。没有必要对最后 4 行做任何事情。
  • 非常感谢@CarySwoveland 我将替换更改为$1;$2\r,现在demo + 底部的附加部分正是我所要求的。我可以轻松地删除应用程序中的这些行。为了完成,是否可以在表达式中添加一些内容以不返回这些行?
  • 我不明白为什么你必须“删除”最后四行。我将其视为读取所有 8 行并返回 4(稍作更改),或者以不同的方式查看,将所有 8 行替换为生成的 4 行。顺便说一句,在我上面提到的 Ruby 代码中,我想我应该写,result = ''; str.gsub(r).each { m = Regexp.last_match; result << "%s;%s\n" % [m[1],m[2]] } #=> "45op0;113-4997\ntr ico;202076\nJJB Be;acure\ntyuh;sala mandra\n"。我早上再回来看看。
  • 我必须删除最后 4 行,因为所需的结果已经在前 4 行。我没有使用 Ruby 或任何类似的语言。 Regex 比我正在使用的应用程序快很多数量级,因此 Regex 可以做的越多越好。即使取一个结果并对其应用另一个正则表达式,也是有益的。你所提供的已经足够好了。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
  • 2015-01-14
  • 2018-07-04
  • 2016-07-30
  • 2012-03-03
  • 1970-01-01
相关资源
最近更新 更多