如何 Grep 在 lookbetween 中搜索两次出现的字符

How to Grep Search two occurrences of a character in a lookbetween

每次我需要一些高级的东西时,我似乎都必须永远重新学习 Regex 和 Grep 语法。这一次,即使有 BBEDIT 的模式游乐场,我也无法解决这个问题。

我需要进行多行搜索,以查找 plist/XML 文件中一对标签之间文本中任意位置出现的两个文字星号。

我可以成功构建lookbetween so:

(?s)(?<=<array>).*?(?=</array>)

我尝试将其限制为仅匹配标签之间出现两个星号的情况:

(?s)(?<=<array>).*?[*]{2}.*?(?=</array>)
(?s)(?<=<array>).+[*]{2}.+(?=</array>)
(?s)(?<=<array>).+?[*]{2}.+?(?=</array>)

但他们一无所获。当我删除 {2} 时,我意识到我什至没有正确地构造它来查找一个星号的出现。我尝试转义字符 /* 和 [/*] 但无济于事。

我如何匹配任何出现的 blah blah * blah blah * blah blah?

[*]{2}表示两个星号必须连续。

(.*[*]){2} 是您要查找的内容 - 它包含两个星号,中间有任何内容。

但我们还需要确保正则表达式在同一时间只测试一个标签闭包,因此我们需要使用 ((?!<\/array>).)* 而不是 .* 来确保它不会在匹配 .*

时消耗结束标记 </array>

正则表达式可以写成:

(?s)(?<=<array>)(?:((?!<\/array>).)*?[*]){2}(?1)*

查看测试结果here

使用

(?s)(?<=<array>)(?:(?:(?!<\/?array>)[^*])*[*]){2}.*?(?=</array>)

参见 proof

说明

NODE EXPLANATION
(?s) set flags for this block (with . matching \n) (case-sensitive) (with ^ and $ matching normally) (matching whitespace and # normally)
(?<= look behind to see if there is:
  <array> '<array>'
) end of look-behind
(?: group, but do not capture (2 times):
(?: group, but do not capture (0 or more times (matching the most amount possible)):
(?! look ahead to see if there is not:
</?array> </array> or <array>
) end of look-ahead
[^*] any character except: '*'
)* end of grouping
[*] any character of: '*'
){2} end of grouping
.*? any character (0 or more times (matching the least amount possible))
(?= look ahead to see if there is:
</array> '</array>'
) end of look-ahead