TofuBug
TofuBug

Reputation: 603

Combining two regular expressions

I've got a question about accomplishing something in regular expressions i.e is it possible and if so how.

Short synopsis of what I am doing: I read Manga online. I like to open up the current issue in a new tab but I don't always remember to click the link with a middle click.

So I decided to write a Greasemonkey script that would run on any of the sites pages adding a target="_blank" to any anchor tag that references a manga or an issue of that manga so a regular click would open it in a new tab. The script itself is working fine, nothing spectacular about it.

Now onto the caveat:

The link patterns we'll call it for each Manga is as follows

    <language of manga>/<manga name> 
      links to the main about page for the manga

    <language of manga>/<manga name>/<issue number> 
      links to the issue number itself

    <language of manga>/<manga name>/<issue number>/<page number> 
      links to the specific page of the issue

Now I want it to always make the first two open in a new tab but I do NOT want the last one to open in a new tab. The reason for this is when reading the actual Manga each click to advance the page would open a new tab.

So to accomplish this I have two regular expressions:

    var MangaIssueRegex = /en-manga\/[A-Za-z0-9\-]+\//;
    var MangaIssuePageRegex = /en-manga\/[A-Za-z0-9\-]+\/(\d+\/){2}/

The first regex picks up any of the three manga link patterns. The second regex picks up only the third manga link pattern (the one for a specific page)

In a nutshell the Greasemonkey script loops through all the anchor tags on the page when it loads and if the href attribute of the anchor tag passes the MangaIssueRegex AND fails the MangaIssuePageRegex the anchor tag is modified to open in a new tab otherwise the anchor tag is not modified.

Now is it possible to combine both regular expressions into a single one that will match the first two patterns but fail if the third pattern is encountered?

Here is the whole script:

    var MangaIssueRegex = /en-manga\/[A-Za-z0-9\-]+\//;
    var MangaIssuePageRegex = /en-manga\/[A-Za-z0-9\-]+\/(\d+\/){2}/
    var elements = document.getElementsByTagName("a");
    for (var i = 0; i < elements.length; i++)
    {
      if (MangaIssueRegex.test(elements[i].getAttribute("href")) && !MangaIssuePageRegex.test(elements[i].getAttribute("href")))
      {
        elements[i].setAttribute("target","_blank");
        elements[i].setAttribute("title","Opens in another tab");
      }
    }

Update

Thanks to both @DanielHilgarth and @iMoses for helping me figure this out

I found out I can use jQuery in Greasemonkey so in the end this is what I ended up with as the complete working script

$("a")
  .filter(function(){return /en-manga\/[\w\-]+\/(\d+\/)?$/.test(this.href);})
  .each(function(index){$(this).attr({title:"Opens in new tab",target:"_blank"});});

Upvotes: 4

Views: 2931

Answers (3)

darkliquid
darkliquid

Reputation: 4109

Looks like you want to match the first regex when it ends, in which case try changing it to:

var MangaIssueRegex = /en-manga\/[A-Za-z0-9\-]+\/?$/

http://jsfiddle.net/ZTGuB/1/

Upvotes: 0

iMoses
iMoses

Reputation: 4348

For matching only the first two patterns try using:

var MangaIssuePageRegex = /en-manga\/[A-Za-z0-9\-]+\/(\d+\/)?$/

This will match:

<language of manga>/<manga name> 

As well as:

<language of manga>/<manga name>/<issue number> 

If you don't wish to enforce a closing backslash, use this Regex instead:

var MangaIssuePageRegex = /en-manga\/[A-Za-z0-9\-]+(\/\d+)?(\/)?$/

Upvotes: 3

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174299

Can't you just add the text end anchor at the end?

Something like this:

/en-manga\/([A-Za-z0-9\-]+\/){1,2}$/

This would match

en-manga/asd/
en-manga/asd/12/

But not

en-manga/asd/12/123/

You can test it yourself.

Upvotes: 2

Related Questions