0

I need to replace all the <a href="/ with <a href="https://link.com/ , but only between COMMENTS tag/field.

Can I do this with a regex?

<!-- COMMENTS -->
    <div class="searchField">
        <div align="right">

            <a href="/website-1.html"><img src="index_files/flag_lang_ro.jpg" title="ro" alt="ro" width="28" height="19" /></a>&nbsp; <a href="/fr/website-2.html"><img src="index_files/flag_lang_fr.jpg" title="fr" alt="fr" width="28" height="19" /></a>&nbsp; <a href="website-3.html"><img src="index_files/flag_lang_en.jpg" title="en" alt="en" width="28" height="19" /></a>&nbsp; <a href="/es/website-4.html"><img src="index_files/flag_lang_es.jpg" title="es" alt="es" width="28" height="19" /></a>&nbsp; <a href="/pt/website-5.html"><img src="index_files/flag_lang_pt.jpg" title="pt" alt="pt" width="28" height="19" /></a>&nbsp; <a href="/ar/website-6.html"><img src="index_files/flag_lang_ae.jpg" width="28" height="19" title="ar" alt="ar" /></a>&nbsp; <a href="/zh/website-7.html"><img src="index_files/flag_lang_zh.jpg" width="28" height="19" title="zh" alt="zh" /></a>&nbsp; <a href="/hi/website-8.html"><img src="index_files/flag_lang_hi.jpg" width="28" height="19" title="hi" alt="hi" /></a>&nbsp; <a href="/de/website-9.html"><img src="index_files/flag_lang_de.jpg" width="28" height="19" title="de" alt="de" /></a>&nbsp; <a href="/ru/website-10.html"><img src="index_files/flag_lang_ru.jpg" width="28" height="19" title="ru" alt="ru" /></a></div>
<!-- COMMENTS -->
2
  • 2
    This answer exactly. Dec 25, 2020 at 11:01
  • @KamilMaciorowski That answer is quote pedantic. I know overuse of regex is an issue in coding, but honestly in a case like this there are ways to achieve this. That said, the larger issue here is the original poster is effectively asking the community to code an answer for them from scratch when no work is really shown by the original poster to see what they have done so far. Honestly, depending on the size of the codebase here, I can easily see this solved with a basic code editor such as Atom. But hey… Dec 27, 2020 at 1:36

3 Answers 3

0

SEARCH:

(?s)(<\!-- COMMENTS -->|\G)((?!^<).)+?<a href="\K(?=/)

REPLACE BY:

https://link.com

5
  • 1
    @Just Me: Be aware that doesn't work if you have href outside <!-- COMMENTS --> as shown in harrymc's answer.
    – Toto
    Dec 26, 2020 at 10:11
  • hi, Toto. No, I don't have href outside <!-- COMMENTS -->. It was the best solution I was waiting for. Thanks everyone.
    – Just Me
    Dec 26, 2020 at 12:06
  • @JustMe: If you have no href outside <!-- COMMENTS -->, why refer to it? Just use: Find:<a href="/ & Replace: <a href="https://link.com/
    – Toto
    Dec 27, 2020 at 9:49
  • @Toto I didn't refer it. Did you read my question carefully? I never use the word outside . I write only between COMMENTS tag/field. So, I believe that between was the key word.
    – Just Me
    Dec 27, 2020 at 10:38
  • @JustMe: If you only have href between <!-- COMMENTS --> and no one outside, there're no needs to refer to <!-- COMMENTS --> in the regex. But if it exists href not between <!-- COMMENTS -->, the above regex doesn't work. As shown in harrymc's test case.
    – Toto
    Dec 27, 2020 at 11:10
0

This is an impossible job for regular expressions. The reason is that there is an unknown number of <a href="/ occurrences between the COMMENTS texts.

Even applying multiple times a regex that replaces one single occurrence of <a href="/ at a time wouldn't work, because it will happily also find the href in text such as:

<!-- COMMENTS -->
...
<!-- COMMENTS -->
...<a href="/...
<!-- COMMENTS -->
...
<!-- COMMENTS -->

You would need a script written in some programming language to do this kind of replacement (possibly using regex for searching), rather than doing the whole thing with only one regex replacement.

2
  • I was thinking of something like that: SEARCH: <\!-- COMMENTS -->(?s)(.*)(<a href="/).*?(?s)<\!-- COMMENTS --> REPLACE BY: <\!-- COMMENTS -->\1<a href="https://link.ca/\2<\!-- COMMENTS -->
    – Just Me
    Dec 25, 2020 at 17:24
  • That's my point - it wouldn't work because you will need to apply it multiple times. In my example above it will replace an href between COMMENTS 1 & 2, and the second time it will find the one between COMMENTS 2 & 3.
    – harrymc
    Dec 25, 2020 at 18:59
0

To answer your question: no, you can't.

Reasons are detailed elsewhere, but the gist of them is that Html allows too much freedom for regex to handle.

  • Html code can have unlimited amounts of spaces, tabs and especially new lines, that make it difficult to write a good regular expression for.
  • Added to that there are several types of "grouping" that can be nested:
    • tags between < and >
    • contents between <tag> and </tag> (and <tag>s without closing </tag>s)
    • quoted attribute values in tags, like <a href="yourlink" title="<a href to confuse you>">
    • comments <!-- ... --> that can contain all of the above (and unclosed comments too, that are closed implicetely after the first > they contain, e.g. that of a <tag>)
  • The final blow is delivered to your regex parser by the total absence of any syntax enforcement, because Html code is never compiled and rarely verified.

To add value to my answer: you need a real Html parser. For tasks like this I still use the old barebones "Lightweight HTML Scanner", a small Java library that is free for many uses, including private, but requires some Java programming to use. I am not aware of any simpler tool than that.

0

You must log in to answer this question.

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