1

I'm looking for a way to find out what page is currently open for a script I'm writing for the browser game TribalWars. The URL's are really similar set up, and this should be easy for somebody who know's what he's doing (which I clearly don't).

The URL looks like this:

https://nlp2.tribalwars.nl/game.php?village=171817&screen=train

The village ID is different for every village (duuh), so that piece should be some kind of wildcard, but the 'train' at the end is what I'm interested in. This means that the user is looking at the page I want my script to modify.

Right now I've written/found the following code:

/^\u0026.+$/ //To find the &, but it doesn't work because there is stuff in front of the &

/^https:\/\/((nl|zz|en).*\.tribalwars\.(nl|net)\/(game.php).*)/ 
//This piece works correctly (stole it from another script), but this will trigger at every page.

In short: I need a regex piece that can find out if the user is looking at a page from the correct domain (like the piece above) and finds out if the tag 'train' is correct.

Thanks :)

MagicLegend
  • 328
  • 1
  • 5
  • 22

4 Answers4

2

var str = 'https://nlp2.tribalwars.nl/game.php?village=171817&screen=train',
    re = /(nl|zz|en).*\.tribalwars\.(nl|net)\/game\.php(\?|.*\&)screen\=train/;

if (re.test(str)) alert('String matches');

Basically what this does is:

  • check for a prefix, either nl, zz, or en (as you provided)
  • followed by whatever
  • followed by the domain name tribalwars
  • followed by its TLD (nl or net)
  • followed by the page you are interested in /game.php
  • followed either by a ? in case screen is the first parameter, or whatever + & if it's not
  • followed by screen=train

Note that it does not matter what comes before or after the RegEx, as we are just testing without any boundary checks like ^ or $.

The last part in detail: (\?|.*\&)screen\=train - a pipe | means OR - we check either for a question mark \?, or for *any number of characters followed by an ampersand .*\&. This is useful if the parameters in your URL are organised differently

If you take a look at the URL that you provided, you will see that there are some parameters in it, after game.php. The list of parameters starts with a ? before the first argument, and after that each argument is separated from the next by &. ?village=171817&screen=train. However, the order of these parameters should not matter, therefore it is possible that the screen parameter is the first one ?screen=train&village=171817 which is then preceded by a question mark and not by an ampersand. So if screen=train is first, there's nothing between that and game.php?. If it's not first, there can be any amount of parameters before it .* followed by an ampersand and the itself.

Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239
  • This is the solution. Thank you! Do you have a min to explain what the regex at the end does? I've read quite a bit about it now, but can you work this bit out for me: (\?|.*\&)screen\=train/ – MagicLegend Nov 22 '16 at 11:36
  • I added some information on the last part of the regex. – Bram Vanroy Nov 22 '16 at 11:46
  • Thank you! I now understand what it does :) Now I know for a fact that the URL will always look like this, but it's always nice to have a failsafe :) – MagicLegend Nov 22 '16 at 11:53
0

Another option to using regEx, is you can use the DOM and a A tag to split url's up for you.

Ok, updated to do more url parsing. The query splitter got from here -. https://css-tricks.com/snippets/jquery/get-query-params-object/

Also made it do the A tag is only created once.

eg.

window.decodeUrl = function decodeUrl(url) {  
  var a = document.createElement('A');
  function inner(url) {  
    a.href = url;
    return {
      protocol: a.protocol,
      hostname: a.hostname,
      pathname: a.pathname,
      search: a.search,
      params: a.search.replace(/(^\?)/,'').split("&").
          map(function(n){return n = n.split("="),
          this[n[0]] = n[1],this}.bind({}))[0]
    }
  };
  window.decodeUrl = inner;
  return inner(url);
}


var url = 'https://nlp2.tribalwars.nl/game.php?village=171817&screen=train';

var durl = decodeUrl(url);

console.log(durl);

console.log(
  'Are we game & train : ' + 
  ((durl.pathname === '/game.php') &&
  (durl.params.screen === 'train'))
);
Keith
  • 22,005
  • 2
  • 27
  • 44
  • Good idea! But this checks for the game.php in the URL, while I'm looking if the screen tag is equal to 'train', without looking at the village ID and other tags in the URL (there can be more, for example: /game.php?village=171817&screen=train&mode=mass&) – MagicLegend Nov 22 '16 at 11:34
  • Oh, right.. no problem. I've just update my answer to make a more generic url decoder,.. – Keith Nov 22 '16 at 11:55
  • Damn, that's impressive. I have a lot to learn :) This is really useful for a other portion of this project, because the url parameters will differ between `train` and `mass` (in this form btw: `&screen=train&mode=mass&`) Thank you! Wil definitely use this piece of code for my project! :) – MagicLegend Nov 22 '16 at 12:02
  • Could you explain why you would need that `inner` function? Why not like [this](https://jsfiddle.net/2u4qxrdy/)? – Bram Vanroy Nov 23 '16 at 12:22
  • @BramVanroy `Could you explain why you would need that inner`, yeah sure. It's just a a caching technique, instead of creating the A element every time this function is called, it just creates it once. If you say try putting a `console.log` on the element create part, you will see this version only create's it once if decodeUrl is called multiple times, were as the fiddle you created it creates it every time you call the function. – Keith Nov 23 '16 at 12:32
0

Can't you just use this? Do you need Regex?

var url = "https://nlp2.tribalwars.nl/game.php?village=171817&screen=train";
var urlSplit = url.split("/");
var urlSplitLast = urlSplit[urlSplit.length - 1];
var urlGet = urlSplitLast.split("&");
var urlScreen = urlGet[urlGet.length - 1];
var screen = urlScreen.split("=");
var screenValue = screen[screen.length - 1];
alert(screenValue);
WasteD
  • 758
  • 4
  • 24
  • Well, I used regex because it was the easiest way to check if the current url is the one I need. I use this in a simple if-statement with the location.href.match function to check on what page the user currently is. – MagicLegend Nov 22 '16 at 11:39
0

Please review this one, I just continue your already have regex:

var re = /^https:\/\/((nl|zz|en).*\.tribalwars\.(nl|net)\/(game.php)?.*village=(\w+)&screen=(\w+))/g;
var url = "https://nlp2.tribalwars.nl/game.php?village=171817&screen=train";

var match = re.exec(url);
var village = match[5];
var screen = match[6];
console.log("village: " + village, "screen: " + screen);
RizkiDPrast
  • 1,695
  • 1
  • 14
  • 21
  • Hmm, good exercise for me to look at this kind of code, but not exactly what I needed. What I didn't specify in my question was that the regex was for inside an if-statement to check if the user was on the correct page to modify some table content. The regex already suffices for my goal :) – MagicLegend Nov 22 '16 at 11:48
  • Great!! I like regex so much for its performance. I am glad you have found solution for the problem – RizkiDPrast Nov 22 '16 at 12:09
  • To be honest Regex is very slow compared to substring comparison, so whenever possible you should use `substr` or the likes. – Bram Vanroy Nov 23 '16 at 12:16
  • Wao, I am gonna check that out @BramVanroy. Thanks for mentioning – RizkiDPrast Nov 23 '16 at 12:17
  • I think back what I said. If you really want to micro-optimise, it seems quite case-dependent in Javascript. Also which browser you test on seems of importance. http://stackoverflow.com/questions/5296268/fastest-way-to-check-a-string-contain-another-substring-in-javascript – Bram Vanroy Nov 23 '16 at 12:27
  • Ya, each browser respond differently. Points i get is to only use Regex if special pattern is needed, other than that `indexOf` is faster – RizkiDPrast Nov 23 '16 at 12:42