Regex for route matching in Express - regex

I'm not very good with regular expressions, so I want to make sure I'm doing this correctly. Let's say I have two very similar routes, /discussion/:slug/ and /page/:slug/. I want to create a route that matches both these pages.
app.get('/[discussion|page]/:slug', function(req, res, next) {
...enter code here...
})
Is this the correct way to do it? Right now I'm just creating two separate routes.
someFunction = function(req, res, next) {..}
app.get('/discussion/:slug', someFunction)
app.get('/page/:slug', someFunction)

app.get('/:type(discussion|page)/:id', ...) works

You should use a literal javascript regular expression object, not a string, and #sarnold is correct that you want parens for alternation. Square brackets are for character classes.
const express = require("express");
const app = express.createServer();
app.get(/^\/(discussion|page)\/(.+)/, function (req, res, next) {
res.write(req.params[0]); //This has "discussion" or "page"
res.write(req.params[1]); //This has the slug
res.end();
});
app.listen(9060);
The (.+) means a slug of at least 1 character must be present or this route will not match. Use (.*) if you want it to match an empty slug as well.

Related

Angular2 pipe regex url detection

I would like to have a pipe which is detecting any url in a string and creating a link with it. At the moment I created this, which seems not working:
#Pipe({name:'matchUrl'})
export class MatchUrlPipe implements PipeTransform {
transform(value: string, arg?: any): any {
var exp = /https?:\/\/(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*)/g;
return value.replace(exp, "<a href='$1'>$1</a>");
}
}
How can I fix it?
Seems like there are two problems with your implementation:
Your regex has the first capturing group ( $1 ) matching the 'www' part of the url. You want to change the regex like this for it to work (note the extra pair of parethesis at the start and end of the regex):
var exp = /(https?:\/\/(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g;
Pipes can't render html normally. You need a trick to do that as mentioned in other questione like this. You need to assign your 'piped value' to the attribute outerHTML of a span for example (the span will not be rendered).
Plunker example

Get suffix from Expressjs routing

I have requests like the followings:
/name-of-anything-1/another-name-2/and-a-third-name-3
I want to be able to get the suffix in a param (-1, -2 and -3 in this cases). I had the next route but doesn't work:
app.get('/:optional-:suffix?*', function(req, res) {
//anything
}
I obtain the first '-' and I need the last one and the rest at 'optional' param.
Thx in advance.
You can just split the whole string at hyphen - and get the last one out
app.get('/:optional', function(req, res){
var suffix = req.params[optional].split('-').reverse()[0];
}

Express.JS regular expression for example.com/:username

// ex: http://example.com/john_smith
app.get('/^(a-z)_(0-9)', function(req, res) {
res.send('user');
});
// ex: http://example.com/john_smith/messages/1987234
app.get('/^(a-z)_(0-9)/messages/:id', function(req, res) {
res.send('message');
});
I wrote the above code for an app that I want to pass a username as a url variable to node.js like I would do: $username = $_GET['username']; in PHP. I'm not too good at writing regular expressions so I wanted to see if anyone could set me on the right track. Thanks in advance.
From your requirement it doesn't seem like you need a regular expression. Just use a a variable in your rule, like below:
// Grabs whatever comes after /user/ and maps it to req.params.id
app.get('/user/:id', function (req, res) {
var userId = req.params.id;
res.send(userId);
});
If you want to have better control, you could use a regular expression. To grab things you are interested in from the expression, use a capture group (which are typically expressed as a set of matching parenthesis):
// Grabs the lowercase string coming after /user/ and maps it to req.params[0]
app.get(/^\/user\/([a-z]+)$/, function (req, res) {
var userId = req.params[0];
res.send(userId);
});
A little off topic, but here's a really good intro to express.js that will help you understand it better (including how the routes work):
http://evanhahn.com/understanding-express-js/
You're looking for req.params, which is an array of all of the capture groups in the regex.
The capture groups start at 1; req.params[0] is the entire match.

Pre-routing with querystrings with Express in Node JS

I'm trying to use express to parse the querystring in case certain parameters are set and execute a little piece of code, before the actual routing is happening. The use-case is to grab a certain value, that could be set, independant of what link is being used. I use express' functionality to pass the stuff to the next possible rule using next().
So far, I tried - at the very top of all the app.get/post-rule-block:
app.get('[?&]something=([^&#]*)', function(req, res, next) {
var somethingID = req.params.something;
// Below line is just there to illustrate that it's working. Actual code will do something real, of course.
console.log("Something: "+somethingID);
next();
})
app.get('/', site.index);
and also:
app.param('something', function(req, res, next) {
var somethingID = req.params.something;
console.log("Something: "+somethingID);
next();
})
app.get('/', site.index);
Example of what should be triggered:
URL: www.example.com/?something=10239
URL: www.example.com/superpage/?something=10239
URL: www.example.com/minisite/?anything=10&something=10239
Unfortunately, none of my solutions actually worked, and all that happens is, that the next matching rule is triggered, but the little function above is never executed. Anybody have an idea, of how this can be done?
EDIT: I do understand, that the param-example wasn't working, as I'm not using said parameter within any other routing-rule afterwards, and it would only be triggered then.
I also do understand, that logic implies, that Express ignores the querystring and it is normally parsed within a function after the routing already happened. But as mentioned, I need this to be "route-agnostic" and work with any of the URL's that are processed within this application.
express does not allow you to route based on query strings. You could add some middleware which performs some operation if the relevant parameter is present;
app.use(function (req, res, next) {
if (req.query.something) {
// Do something; call next() when done.
} else {
next();
}
});
app.get('/someroute', function (req, res, next) {
// Assume your query params have been processed
});
Ok, there is quite a logical flaw in here. Routing only uses the URL, and ignores the querystring.
The (or better "A") solution is actually this:
app.get('*', function(req, res, next) {
if (req.query.something) {
console.log("Something: "+req.query.something);
};
next();
})
Explanation: As Express is ignoring the querystring for the routing, the only regular expression matching all URL's is "*". Once that is triggered, I can check if said querystring is existing, do my logic and continue the routing matching the next rule by using "next()".
And yes: facepalm

Regular Expression in Node.js Express Router

I have tried to find a way to enter regular expression into an express routing URL and then access the variable portion of the URL through the request object. Specifically I want to route to the url "/posts/" + any number of digits. Is there a way to do this?
Examples:
/posts/54
/posts/2
/posts/546
This should do it:
app.get('/posts/:id(\\d+)', function(req, res) {
// id portion of the request is available as req.params.id
});
EDIT: added regex to path to limit it to digits
I agree with Johnny, my only addition being that you can do this for any number of levels. For example:
app.get('/users/:id/:karma', function(req, res){
//Both req.params.id and req.params.karma are available parameters.
});
You should also check out the express documentation: http://expressjs.com/api.html.
The request section would probably prove quite useful to you.