【问题标题】:Match everything between TWO separator charcters匹配两个分隔符之间的所有内容
【发布时间】:2019-05-14 07:39:45
【问题描述】:

我想匹配由左右两个字符组成的分隔符之间的所有内容。例如。 <<Hello>> 其中<<>> 是分隔符。这适用于正则表达式\<\<([^\>]+)\>\>

但在 匹配的 字符串中需要有单个分隔符 <>,例如 <<\<Hello\>>>,其中 \<Hello\> 应该匹配。

这不起作用。

我尝试了否定的前瞻:\<\<((?!\>)[^\>]+)\>\>,但没有成功。

我需要能够转义分隔符。

有什么想法吗?

【问题讨论】:

  • 试试<<([^\\>]*(?:\\.[^\\>]*)*)>>,见regex101.com/r/0CiEbi/1
  • 谢谢!!就是这样......几乎......当我在<<Hello\>\>>>上尝试它时,它匹配<<Hello\>\` (with a backslash at the end but not the following >`)
  • 能否请您添加一些有效/无效的字符串? BTW,用上面的<<Hello\>\>>>字符串,捕获的值为Hello\>\>,见regex101.com/r/0CiEbi/2
  • 这个<<Hello\>\>>> <<Test>> 应该有两个匹配项:Hello\>\>Test
  • 我使用 PowerShell (.NET) 对其进行了测试:$r = [regex]"<<([^>]*(?:>(?!>)[^>]*)*)>>"; $r.Matches("<<Hello\>\>>> <<Test>>").groups 结果:组:{0, 1} 成功:真实名称:0 捕获:{0} 索引:0 长度:12 值:\>> 成功:真实名称:1 捕获:{1} 索引:2 长度:8 值:Hallo\>\ 组:{0, 1} 成功:真实名称:0 捕获:{0}索引:14 长度:8 值:> 成功:真实名称:1 捕获:{1} 索引:16 长度:4 值:测试

标签: regex


【解决方案1】:

你可以使用

$r = [regex]'(?<=(?<!\\)(?:\\{2})*)<<([^\\>]*(?:\\.[^\\>]*)*)>>'
$res = $r.Matches('<<Hello\>\>>> <<Test>>') | % {$_.Groups[1].value}

或者

$res = $s | Select-String -Pattern '(?<=(?<!\\)(?:\\{2})*)<<([^\\>]*(?:\\.[^\\>]*)*)>>' -AllMatches | % {$_.matches.groups[1].value}

请参阅regex demo

如果您希望在不访问第 1 组的情况下获得比赛,请将 &lt;&lt;&gt;&gt; 放入 (?&lt;=&lt;&lt;)lookbehind / (?=&gt;&gt;)lookahead:

$r = [regex]'(?<=(?<!\\)(?:\\{2})*<<)[^\\>]*(?:\\.[^\\>]*)*(?=>>)'
$res = $r.Matches("<<Hello\>\>>> <<Test>>") | % {$_.value}

或者

 $res = $s | Select-String -Pattern '(?<=(?<!\\)(?:\\{2})*<<)[^\\>]*(?:\\.[^\\>]*)*(?=>>)' -AllMatches | % {$_.matches.value}

this regex demo

输出:

Hello\>\>
Test

模式详情

  • (?&lt;=(?&lt;!\\)(?:\\{2})*) - 初始 &lt;&lt; 中的第一个 &lt; 本身不能被转义,否则,它不是有效匹配
  • &lt;&lt; - &lt;&lt; 子字符串
  • ([^\\&gt;]*(?:\\.[^\\&gt;]*)*) - 捕获组 1:
    • [^\\&gt;]* - 除了 \&gt; 之外的 0 个或多个字符
    • (?:\\.[^\\&gt;]*)* - 除了换行符以外的任何转义字符的零次或多次重复,然后是 \&gt; 以外的 0 次或更多字符
  • &gt;&gt; - &gt;&gt; 子字符串。

【讨论】:

  • 看起来很棒!谢谢你,维克托!!
  • @IngoKarstein 实际上,模式的开头必须有(?&lt;=(?&lt;!\\)(?:\\{2})*)。我编辑了答案。
【解决方案2】:

你也可以使用这个模式(?&lt;=&lt;&lt;).+?(?=&gt;&gt;)

解释:

(?&lt;=&lt;&lt;) - 正面向后看,确保前面是&lt;&lt;

.+? - 匹配一个或多个任意字符,非贪婪

(?=&gt;&gt;) - 正向前瞻,确保后面是&gt;&gt;

Demo

【讨论】:

  • 这并不是在所有情况下都有效:当我测试&lt;&lt;Hello&gt;&gt;&lt;&lt;Test&gt;&gt; 时,我得到了Hello&gt;&gt;&lt;&lt;Test 组。
【解决方案3】:

用这个怎么样:

\<{2}(.*?)\>{2}(?!\>)

您在第 1 组中获得所需的输出。

解释:

  1. \&lt;{2} 以 2 开头
  2. (.*?)\&gt;{2} 匹配所有内容,除非连续达到两个 >>
  3. (?!\&gt;) 在第 2 步为真之后,它必须确保下一个字符不是 >(负前瞻)

Regex101 sample

【讨论】:

    【解决方案4】:

    您可以使用以下模式:&lt;&lt;(.*?[^\\]?)(?=&gt;&gt;)&gt;&gt;

    适用于以下情况:

    <<\<Hello\>>>
    <<Hello>><<Test>>
    <<>>
    

    See explanation...

    【讨论】:

      猜你喜欢
      • 2020-06-30
      • 2018-12-22
      • 2020-10-30
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      相关资源
      最近更新 更多