【问题标题】:Regex matching between lines行之间的正则表达式匹配
【发布时间】:2020-11-25 10:07:52
【问题描述】:

我有以下文本块:

## 8.6.0
- **Upload date:** November 19, 2020
- **Release date:** TBC
- **Internal version:** 1171

### Feature
- dsfdsfds
- sdfdsf
- dsfdsf

### Bug fixes
- sdfsaf
- sdfsad
- sdfsdfdsf

### Internal
- sadfsdfsda
- fsdfgsadfasd
- sdfsda

## 8.5.1
- **Upload date:** November 09, 2020
- **Release date:** November 12, 2020
- **Internal version:** 1170

我想只提取第一个条目,例如从## 8.6.0 的第一个字符开始到## 8.5.1 的第一个字符之前的所有文本。

我尝试了以下表达式:

[#].*[0-9])(.*?)([#].*[0-9])

但它不会返回正确的结果。这个表达式怎么写?

【问题讨论】:

  • 你可以试试^(##\h*[\d.]+[\s\S]*?)##\h*[\d.]+
  • 您并没有真正解释所有条件,而是尝试使用 \A\#\#\s*\d[\s\S]+?(?=\#\#\s*\d|\Z) 之类的内容。这是demo
  • 你可以使用这个(?=#{2}\s*[\d.]+)[^]+(?=#{2}\s*\d\.?)

标签: regex


【解决方案1】:

使用

^##(?!#).*(?:\n(?!##(?!#)).*)*

请参阅regex demo

详情

  • ^ - 字符串的开头(如果您在默认启用多行标志的环境中使用它,请尝试在其前面加上(?-m) 或使用^(?<![\s\S])
  • ##(?!#) - 一个 ## 子字符串后面没有另一个 #
  • .* - 该行的其余部分
  • (?:\n(?!##).*)* - 零行或多行不以 ## 开头,后跟另一个 #

【讨论】:

  • 这样做的好处是不包括最后的换行符,假设这实际上是可取的。
【解决方案2】:

如果我对问题的理解正确,那么

^## (\d+\.?){3}.+?(?=## \d)

应该可以。 Here's a demo.

该模式执行以下操作:

  • 查找两个哈希值,后跟一个版本号,就在字符串的开头 - ^## (\d+\.?){3}
  • 向前寻找另外两个哈希值,后跟一个数字(下一组注释的开头)-(?=## \d)
  • 抓取两者之间的所有字符,以尽可能少的字符为目标 - .+?

要完成这项工作,您需要启用 dotall 标志,以便 . 可以匹配换行符。

【讨论】:

  • 如果有的话,请注意您的正则表达式will match 跨越更多部分。 My solution 仍将正确匹配第一部分。
  • 很好,谢谢 - 我已将我的更新为不那么贪婪。
  • 还有两件事:1) ## \d 匹配一行中的任何位置,不仅在开头,这同样可能不受欢迎,2) your regex (499) 需要双倍的数量由于我的解决方案中使用了unroll-the-loop principle,比mine (123) 的步骤多。
  • 再次感谢您——您说的完全正确。我可以很容易地修复 line-start 的问题,但这会使我的效率更低。我将通读展开原理链接。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 2016-09-02
  • 2021-08-24
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多