1

Since you can't use negative lookbehinds in JavaScript, how would you achieve the same regex match without one, using a lookahead or some other JavaScript supported method?

(?<!<\/strong>\n\s{4}|<\/strong>&nbsp;\n\s{4})<br>

I'm trying to find all <br> tags that are not preceded by </strong> and </strong>&nbsp; followed by a line break and a series of whitespace chars.

Here's my code and some sample text for testing. I got it working in pcre with the lookbehind but I can't figure out how to make it work in JavaScript.

I've tried the other examples here but I was unable to figure out how to implement those solutions according to my needs.

UPDATE Javascript lookbehinds are coming in ES2018!

selfagency
  • 1,481
  • 1
  • 9
  • 12

2 Answers2

1

A non-regular expression approach

When parsing HTML, I prefer to convert HTML into DocumentFragments. This allows me to use common querySelector methods and JS functions to achieve my end goal.

I replace the 3 br tags with a the following: <div>REPLACED</div>. Also, in order to create the fragment, I used the npm package html-fragment.

const html = `<p><strong>It was a weak bit.</strong>&nbsp;
    <br>Because it&rsquo;s already been done. If he had been like, &ldquo;I don&rsquo;t know, do you want to go to the La Brea tar pits and scoop some tar out and give ourselves a facial and burn ourselves and then only be able to know each other?&rdquo; I would be like, &ldquo;Haa, what?! Okay.&rdquo; I mean, something new is going on here. He basically did the equivalent of like when guys do &ldquo;fat guy in a little coat,&rdquo; and they act like it&rsquo;s not a Chris Farley callback. It&rsquo;s like, this is a joke that&rsquo;s in our system, so you&rsquo;re a little bit unoriginal or even worse, you don&rsquo;t know you&rsquo;re unoriginal.&nbsp;</p>
<p><strong>Does he know it&rsquo;s you?</strong>&nbsp;
    <br>I do think he knew that I was a comedian named Jenny. So anyway, he&rsquo;s like, &ldquo;Let&rsquo;s go to the Renaissance fair,&rdquo; and I call my friends, and I&rsquo;m like, &ldquo;I&rsquo;m not going on this date.&rdquo; And they&rsquo;re like, &ldquo;Oh Jenny, come on, don&rsquo;t be so closed down, you need to get out there.&rdquo; I&rsquo;m like, &ldquo;UGH, fine.&rdquo; Then we have a series of text messages back and forth that I&rsquo;m just kind of like, <em>What is this? Is this what dating is like?</em> I was with my ex-husband for nine years, then I was in a very serious relationship that was passionate for a year, and I&rsquo;m like, I don&rsquo;t know, maybe I just don&rsquo;t know what&rsquo;s going on. And he&rsquo;s asking me these questions that I&rsquo;m like, What. The. Fuck. Why don&rsquo;t you just wait?</p>
<p><strong>What is he asking you?</strong>&nbsp;
    <br>Like, &ldquo;Where was the last place you flew on an airplane?&rdquo; And I&rsquo;m not a rude or cruel woman, but I was like, I don&rsquo;t... dude... just wait. Sit me down, I&rsquo;ll tell you anything, just wait. Just wait until Saturday.</p>
<p><strong>Also, that&rsquo;s the kind of question that is like, &ldquo;I&rsquo;m gonna go on the internet and search random questions to ask someone.&rdquo;</strong>&nbsp;
    <br>Yeah, it&rsquo;s not great. It&rsquo;s a real speed-dating question. I would love it in other circumstances if it was like a page in <em>Entertainment Weekly</em>, you know? So then I&rsquo;m like, &ldquo;I made us a reservation at this restaurant, will you meet me there?&rdquo; He&rsquo;s like, &ldquo;Yes, is it fancy?&rdquo; I&rsquo;m like, &ldquo;No,&rdquo; and he&rsquo;s like, &ldquo;Okay, should I wear something like this?&rdquo; And he sends me a picture of a knight&rsquo;s costume. Like from the Renaissance fair. At which point I&rsquo;m like what the fuck, dude? Because I didn&rsquo;t even jump on this riff in the first place. It&rsquo;s not like I was like, &ldquo;Yes, and I will wear my wench&#39;s costume and bring a cup of mead!&rdquo; I&rsquo;m just like... Heh?! What? Why are you doing this?</p>
<p><strong>You didn&rsquo;t respond positively to the bit.</strong>
    <br>Never. Anyway, on the day of the date, I was like, &ldquo;How will I know it&rsquo;s you?&rdquo; And I thought he would be like, &ldquo;I&rsquo;m 6&rsquo;1&rdquo; and I&rsquo;ve got a beard,&rdquo; or some
<p><br></p>
<p><br></p>
<p><br></p>`;

const fragment = HtmlFragment(html);
Array.from(fragment.querySelectorAll('br'))
  .filter(br => {
    let previous = br.previousElementSibling;
    return (previous === null || previous.nodeName !== 'STRONG');
  })
  .forEach(br => {
    let div = document.createElement('div');
    div.innerText = 'REPLACED';
    br.parentNode.replaceChild(div, br);
  });

let div = document.createElement('div');
div.appendChild(fragment);

console.log(div.innerHTML);
<script src="https://unpkg.com/html-fragment@1.1.0/lib/html-fragment.min.js"></script>
KevBot
  • 17,900
  • 5
  • 50
  • 68
  • if i'm going to go that route, then i'd rather just use jquery or cheerio `$('br').each(function () { if (!$(this).siblings('strong')) $(this).remove() })` – selfagency Jul 18 '17 at 17:44
  • @selfagency, so is the general idea then to remove br tags that are the only child of p tags? – KevBot Jul 18 '17 at 18:56
0

You have to match it to go past it.
There is no other way at all !!!!

/(<\/strong>\n\s{4}|<\/strong>&nbsp;\n\s{4})?<br>/

Within a callback, if group 1 is not null

https://regex101.com/r/xVJhGl/1

var text =
"<p><strong>It was a weak bit.</strong>&nbsp;\n"
+ "    <br>Because it&rsquo;s already been done. If he had been like, &ldquo;I don&rsquo;t know, do you want to go to the La Brea tar pits and scoop some tar out and give ourselves a facial and burn ourselves and then only be able to know each other?&rdquo; I would be like, &ldquo;Haa, what?! Okay.&rdquo; I mean, something new is going on here. He basically did the equivalent of like when guys do &ldquo;fat guy in a little coat,&rdquo; and they act like it&rsquo;s not a Chris Farley callback. It&rsquo;s like, this is a joke that&rsquo;s in our system, so you&rsquo;re a little bit unoriginal or even worse, you don&rsquo;t know you&rsquo;re unoriginal.&nbsp;</p>\n"
+ "<p><strong>Does he know it&rsquo;s you?</strong>&nbsp;\n"
+ "    <br>I do think he knew that I was a comedian named Jenny. So anyway, he&rsquo;s like, &ldquo;Let&rsquo;s go to the Renaissance fair,&rdquo; and I call my friends, and I&rsquo;m like, &ldquo;I&rsquo;m not going on this date.&rdquo; And they&rsquo;re like, &ldquo;Oh Jenny, come on, don&rsquo;t be so closed down, you need to get out there.&rdquo; I&rsquo;m like, &ldquo;UGH, fine.&rdquo; Then we have a series of text messages back and forth that I&rsquo;m just kind of like, <em>What is this? Is this what dating is like?</em> I was with my ex-husband for nine years, then I was in a very serious relationship that was passionate for a year, and I&rsquo;m like, I don&rsquo;t know, maybe I just don&rsquo;t know what&rsquo;s going on. And he&rsquo;s asking me these questions that I&rsquo;m like, What. The. Fuck. Why don&rsquo;t you just wait?</p>\n"
+ "<p><strong>What is he asking you?</strong>&nbsp;\n"
+ "    <br>Like, &ldquo;Where was the last place you flew on an airplane?&rdquo; And I&rsquo;m not a rude or cruel woman, but I was like, I don&rsquo;t... dude... just wait. Sit me down, I&rsquo;ll tell you anything, just wait. Just wait until Saturday.</p>\n"
+ "<p><strong>Also, that&rsquo;s the kind of question that is like, &ldquo;I&rsquo;m gonna go on the internet and search random questions to ask someone.&rdquo;</strong>&nbsp;\n"
+ "    <br>Yeah, it&rsquo;s not great. It&rsquo;s a real speed-dating question. I would love it in other circumstances if it was like a page in <em>Entertainment Weekly</em>, you know? So then I&rsquo;m like, &ldquo;I made us a reservation at this restaurant, will you meet me there?&rdquo; He&rsquo;s like, &ldquo;Yes, is it fancy?&rdquo; I&rsquo;m like, &ldquo;No,&rdquo; and he&rsquo;s like, &ldquo;Okay, should I wear something like this?&rdquo; And he sends me a picture of a knight&rsquo;s costume. Like from the Renaissance fair. At which point I&rsquo;m like what the fuck, dude? Because I didn&rsquo;t even jump on this riff in the first place. It&rsquo;s not like I was like, &ldquo;Yes, and I will wear my wench&#39;s costume and bring a cup of mead!&rdquo; I&rsquo;m just like... Heh?! What? Why are you doing this?</p>\n"
+ "<p><strong>You didn&rsquo;t respond positively to the bit.</strong>\n"
+ "    <br>Never. Anyway, on the day of the date, I was like, &ldquo;How will I know it&rsquo;s you?&rdquo; And I thought he would be like, &ldquo;I&rsquo;m 6&rsquo;1&rdquo; and I&rsquo;ve got a beard,&rdquo; or some\n"
+ "<p><br></p>\n"
+ "<p><br></p>\n"
+ "<p><br></p>\n"
;

var rx = /(<\/strong>\n\s{4}|<\/strong>&nbsp;\n\s{4})?<br>/g;

text = text.replace( rx , function(match, a)
    {
        if ( a )
            return match;
        return "<REPL>";
    }
);

console.log( text );
  • thanks. this was also the furthest i got trying to do it in js vs. pcre. i suppose it may be my best option just creating a function off .replace() to ignore this case rather than trying to do it all in the regex. – selfagency Jul 18 '17 at 16:35
  • @selfagency - Posted an example usage. –  Jul 18 '17 at 16:54