我有以下文本,需要从中删除一些wdiff
输出。
text='Иса Мәсіхтің елшісі Петірден [-(-] осы күнәкар дүниеде [-)-] жат жерлік болып, Понти, Ғалатия, [-Қападоқия, Азия және Бітүния аймақтарында шашыраған [ сенушілерге дұғай сәлем ].-] {+Қападоқия… https://t.co/.......... [Петірдің 1 1:1-5]+}'
我正在尝试使用[- -]
非贪婪的 perl regex 删除文本块\[-.*?-\]
,但它也与之前的块匹配:
$ perl -pe 's|\[-.*?-\] {\+(\S+… https://t.co/.*)\+}|\1|' <<<"$text"
Иса Мәсіхтің елшісі Петірден Қападоқия… https://t.co/.......... [Петірдің 1 1:1-5]
预期输出:
$ perl -pe 's|\[-.*?-\] {\+(\S+… https://t.co/.*)\+}|\1|' <<<"$text"
Иса Мәсіхтің елшісі Петірден [-(-] осы күнәкар дүниеде [-)-] жат жерлік болып, Понти, Ғалатия, Қападоқия… https://t.co/.......... [Петірдің 1 1:1-5]
答案1
我已将您的输入字符串简化为qABxBCzABxBCDEFw
, 其中
A represents [
B represents -
C represents ]
D represents {\+
E represents the text between the +s (including the URL)
F represents \+}
Lower case letters represent everything else.
因此,这里有一些针对输入运行的替代命令:
Command Output
0. Input text: qABxBCzABxBCDEFw
1. Non-greedy: 's|AB.*?BCD(E)F|\1|' qEw
2. Greedy: 's|AB.*BCD(E)F|\1|' qEw
3. Restricted Non-greedy: 's|AB[^B]*?BCD(E)F|\1|' qABxBCzEw
4. Restricted Greedy: 's|AB[^B]*BCD(E)F|\1|' qABxBCzEw
5. Constrained Non-greedy: 's|(.*)AB.*?BCD(E)F|\1\2|' qABxBCzEw
6. Constrained Greedy: 's|(.*)AB.*BCD(E)F|\1\2|' qABxBCzEw
命令 1 是您尝试过的命令。命令 2 是同样的事情,但不是非贪婪的。如您所知,它们产生相同的结果。
在我看来,非贪婪仅适用于长度的文本与类似的内容匹配.*
。 不影响起点。 正则表达式匹配总是尽快开始。所以,当你说AB.*?BC
(ie, \[-.*?-\]
) 时,它匹配第一的 [-
在线上。然后,您期望它匹配以 结尾的任何字符的最短可能字符串-]
。您可能期望这会是[-(-]
。但仔细观察:正则表达式是AB.*?BCD(E)F
,因此它必须匹配以 结尾的任何字符的最短可能字符串-] {+
。这迫使它消耗几乎直到 URL 的所有内容。
我已经编写了四个替代命令,它们似乎可以满足您的要求。 “受限”的(3 和 4)搜索的不是AB.*BC
,而是AB[^B]*BC
;用文字来说,AB
…… “……”中BC
没有s。B
在你的例子中,这意味着[-
…… “……”中-]
没有s。 -
“受限”者(5 和 6)通过在它们前面AB.*BC
放置一个贪婪者来迫使比赛尽可能晚地开始。.*
事实证明,你AB.*BC
在这些方面是否贪婪或非贪婪并不重要。
答案2
你必须使用一个消极环视:
perl -pe 's|\[-((?!-\]).)*-\] {\+(\S+… https://t.co/.*)\+}|\2|' <<<$text
问题是第一次出现[-
匹配。那么该模式的非贪婪并没有达到预期的效果,无论它多么非贪婪。使用否定环视,您可以匹配除 string 之外的所有内容-]
,然后它仅匹配该部分之前的出现{+...+}
。