0

I want to add one blank space after any occurrence of:

<span class="negrita">ANYTHING</span>

So, with this SED instruction:

sed -E "s/(<span class=\"negrita\">.*?<\/span>)/\1 /g" <<< 'In <span class="negrita">1959</span> economic policy was reoriented in order to undertake <span class="negrita">the country modernization</span>. More text'

I get this output:

In <span class="negrita">1959</span> economic policy was reoriented in order to undertake <span class="negrita">the country modernization</span> . More text

So, as you can see, it is adding the blank space after the last occurrence, but not after the first one. Isn't the "/g" option meant to indicate that it should replace all occurrences?

Thanks in advance.

3
  • 3
    The '.*' is a greedy match, matching everything between the first match of '<span class"negrita">' and the last match of the closing '</span>'
    – spuck
    May 7, 2020 at 15:15
  • 1
    Does this answer your question? stackoverflow.com/questions/1103149/…
    – spuck
    May 7, 2020 at 15:17
  • 2
    sed in not a tool to parse HTML nor XML May 7, 2020 at 15:24

2 Answers 2

2

*? is not a standard extended regular expression operator.

Depending on the sed or regexp engine implementation, it will either

  1. report an error like on BSDs
  2. be the same as .* (as it's like (.*)?) like on GNU systems
  3. work like perl's *? non-greedy version of * like with ast-open sed
  4. do anything or everything as it's not a standard operator

You seem to be wanting 3, but you're getting 2, probably because your sed is GNU sed.

Note that -E is not a standard sed option either (though will likely be in the next major version of the POSIX specification).

If you want to use perl regexp operators, you should use perl:

perl -pe 's:<span class="negrita">.*?</span>:$& :g'

(that assumes spans don't nest and are not split on several lines)

Or with sed, you could do (assuming the contents of the span doesn't contain any <):

sed 's:<span class="negrita">[^<]*</span>:& :g'
2

try

sed -E "s/(<span class=\"negrita\">[^<]*?<\/span>)/\1 /g" 

where

  • [^<] means any char but <

using your sample (with added ===)

sed -E "s/(<span class=\"negrita\">[^<]*?<\/span>)/\1=== /g"

gives (folded manualy)

In <span class="negrita">1959</span>===  economic policy 
was reoriented in order to undertake <span class="negrita">the 
country modernization</span>=== . More text

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .