REGEX 匹配单行或多行

REGEX matching single line or multiline

使用降价文件,我跟踪我的 activity。
到本周末,我需要生成一份报告,说明我在某个主题上花费了多少时间。

我想做的是:

  1. 从 MASTERFILE(参见 https://pastebin.com/1Qs8f00M)生成我的 activity 的每日详细报告。
  2. 从那些每日报告中(预期结果将是 https://pastebin.com/Pn56B3Fb),提取我的时间报告。

主文件:

## %XXX ProjectName1
<br>

- XXX : Restabat ut Caesar post haec properaret accitus et ...
- XXX : fictisque blanditiis hortabatur...
```
$ various_commands or reminder
```

- XXX : Restabat ut Caesar post haec properaret accitus et abstergendae causa suspicionis sororem suam, eius uxorem, quid moliretur haerebat. : CHRG=0.5
```
Novo denique perniciosoque exemplo idem Gallus ausus est inire flagitium grave, quod Romae cum ultimo dedecore temptasse aliquando dicitur Gallienus, et adhibitis paucis clam ferro succinctis vesperi per tabernas palabatur et conpita quaeritando Graeco sermone, cuius erat inpendio gnarus, quid de Caesare quisque sentiret. 

Sed ut tum ad senem senex de senectute, sic hoc libro ad amicum amicissimus scripsi de amicitia. Tum est Cato locutus, quo erat nemo fere senior temporibus illis, nemo prudentior; nunc Laelius et sapiens (sic enim est     habitus) et amicitiae gloria excellens de amicitia loquetur. 
```
<br>

## %YYY ProjectName2
<br>

- YYY : Restabat ut Caesar post haec properaret accitus et : CHRG=0.25
<br>

后者很简单,因为我的任务是结构化的:

- [ProjectCode] : some details : CHRG=0,5

以下作品比较不错:

Get-Content -Raw .\test.md |
    Select-String '(-.*CHRG=.*)' -AllMatches |
    Foreach {$_.Matches} |
    Foreach {$_.Value}

前者更难:我似乎无法掌握正确的正则表达式

Multiline regex to match config block 开始,到目前为止我尝试了以下但没有成功(我试图找到一个有用的信标或标记,因为我在我的 .MD 文件上使用 PANDOC 来生成 .HTML 文件;两个一石二鸟):

Get-Content -Raw .\test.md |
    Select-String '(?smi)(^## %.*|^-\s.*CHRG=.*).*?<br>' -AllMatches |
    Foreach {$_.Matches} |
    Foreach {$_.Value}

所需的输出将是:

## %XXX ProjectName1
<br>

- XXX : Restabat ut Caesar post haec properaret accitus et abstergendae causa suspicionis sororem suam, eius uxore m, quid moliretur haerebat. : CHRG=0.5
<code>
Novo denique perniciosoque exemplo idem Gallus ausus est inire flagitium grave, quod Romae cum ultimo dedecore tem ptasse aliquando dicitur Gallienus, et adhibitis paucis clam ferro succinctis vesperi per tabernas palabatur et conpita quaeritando Graeco sermone, cuius erat inpendio gnarus, quid de Caesare quisque sentiret.

Sed ut tum ad senem senex de senectute, sic hoc libro ad amicum amicissimus scripsi de amicitia. Tum est Cato locutus, quo erat nemo fere senior temporibus illis, nemo prudentior; nunc Laelius et sapiens (sic enim est habitus) et amicitiae gloria excellens de amicitia loquetur.
</code>
<br>

## %YYY ProjectName2
<br>

- YYY : Restabat ut Caesar post haec properaret accitus et : CHRG=0.25
<br>

实际输出为:

## %XXX ProjectName1
<br>

- XXX : Restabat ut Caesar post haec properaret accitus et ...
- XXX : fictisque blanditiis hortabatur...
<code>
$ various_commands or reminder
</code>

- XXX : Restabat ut Caesar post haec properaret accitus et abstergendae causa suspicionis sororem suam, eius uxorem, quid moliretur haerebat. : CHRG=0.5
<code>
Novo denique perniciosoque exemplo idem Gallus ausus est inire flagitium grave, quod Romae cum ultimo dedecore temptasse aliquando dicitur Gallienus, et adhibitis paucis clam ferro succinctis vesperi per tabernas palabatur et conpita quaeritando Graeco sermone, cuius erat inpendio gnarus, quid de Caesare quisque sentiret.

Sed ut tum ad senem senex de senectute, sic hoc libro ad amicum amicissimus scripsi de amicitia. Tum est Cato locutus, quo erat nemo fere senior temporibus illis, nemo prudentior; nunc Laelius et sapiens (sic enim est habitus) et amicitiae gloria excellens de amicitia loquetur.
</code>
<br>

## %YYY ProjectName2
<br>

- YYY : Restabat ut Caesar post haec properaret accitus et : CHRG=0.25
<br>

正则表达式的这些部分

(^## %.*|^-\s.*CHRG=.*).*?<br>
 ~~~~~~~               ~~~~~~~

匹配从第一个 ## % 到最后一个 <br> 的所有内容,因为交替中的贪婪 .* 和单行修饰符 ((?s))。后者也使点匹配换行符,因此 ^## %.* 将匹配行首的 ## % 以及此后的所有内容 ^-\s.*CHRG= 将匹配一行开头的连字符和 space(好吧,实际上是任何白色 space 字符),直到下一次出现 CHRG=即使在.

之间还有其他以连字符开头和space的行

尝试这样的事情:

(?mi)^(## %.*|-\s.*CHRG=.*)[\s\S]*?<br>

从表达式中删除单行修饰符使交替匹配仅在一行内(因为 . 不会匹配换行符)。 [\s\S]*? 然后对从行尾到下一个 <br> (包括换行符)的所有内容进行非贪婪匹配。