I have the following text from which I need to remove some wdiff output.text='    [-(-]    [-)-]   , , , [-,      [    ].-] {+ https://t.co/.......... [ 1 1:1-5]+}'I'm trying to remove a [- -] block of text with the non-greedy perl regex \[-.*?-\], but it is matching the previous blocks too:$ perl -pe 's|\[-.*?-\] {\+(\S+ https://t.co/.*)\+}|\1|' <<<$text     https://t.co/.......... [ 1 1:1-5]Expected output:$ perl -pe 's|\[-.*?-\] {\+(\S+ https://t.co/.*)\+}|\1|' <<<$text    [-(-]    [-)-]   , , ,  https://t.co/.......... [ 1 1:1-5]
Perl non-greedy regex matching more than it should
regular expression;perl
Ive simplified your input string to qABxBCzABxBCDEFw, whereA 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.So here are some substitute commands run against the input:                                  Command                          Output0. Input text:                                                     qABxBCzABxBCDEFw1. Non-greedy:                   's|AB.*?BCD(E)F|\1|'              qEw2. Greedy:                       's|AB.*BCD(E)F|\1|'               qEw3. Restricted Non-greedy:        's|AB[^B]*?BCD(E)F|\1|'           qABxBCzEw4. Restricted Greedy:            's|AB[^B]*BCD(E)F|\1|'            qABxBCzEw5. Constrained Non-greedy:       's|(.*)AB.*?BCD(E)F|\1\2|'        qABxBCzEw6. Constrained Greedy:           's|(.*)AB.*BCD(E)F|\1\2|'         qABxBCzEwCommand 1 is the one you tried.Command 2 is the same thing, but not non-greedy.As youre aware, they produce the same result.It seems to me that non-greedy applies only to the length of the text matchedby something like .*. It doesnt affect the starting point.Regex matches always begin as soon as they can.So, when you say AB.*?BC (i.e., \[-.*?-\]),its matching the first [- on the line.Then, you expect, its matching the shortest possible stringof any characters ending with -].You might expect that this would be [-(-].But look closer: the regex is AB.*?BCD(E)F,so it must match the shortest possible stringof any characters ending with -]{+.This forces it to consume everything up almost to the URL.I have written four alternative commands that seem to do what you want.The Restricted ones (3 and 4) search, not for AB.*BC,but for AB[^B]*BC; in words, ABBC with no Bs in the .In your case, that means [--] with no -s in the .The Constrained ones (5 and 6) force the AB.*BC match to startas late as possible by putting a greedy .* in front of them.It turns out not to matter whether you do the AB.*BC partas greedy or non-greedy in these, either.