Express route parsing with regex characters sets - node.js

Path: /1,2,3,456,678 - only numbers and commas, not anything else
Should be matched with regex-like path like this: /ids:(\\d+[,\\d]*) natively
But https://www.npmjs.com/package/path-to-regexp in express compiles it to some ridiculous regex
Expressers/noders - pls guide me how to approach this right

Replacing * with {0,} solved the issue
So request /1,2,34,56 matched by path: /ids:(\\d+[,\\d]{,*})
Link to path-to-regexp issue: https://github.com/pillarjs/path-to-regexp/issues/233

Related

Jest configuration, help me decipher this file pattern: [/\\\\]

I was digging around in the example projects in the Next.js project and in the Jest configuration for the Typescript project I found this pattern in the testPathIgnorePatterns in the Jest configuration:
<rootDir>[/\\\\](node_modules|.next)[/\\\\]
What exactly is this? Looks somewhat like a regular expression, but I don't understand the [/\\\\] part?
I would like to extend the expression above with a positive lookahead in order to exclude certain node modules from being ignored, but I'm not quite sure how to achieve this?
This is regular expression, where \\\\ means a single \, so [/\\\\] character class means either / slash or \ backslash character.
The context for it is that it's provided as a string in Jest JSON configuration:
"testPathIgnorePatterns": "<rootDir>[/\\\\](node_modules|.next)[/\\\\]"
The string is supposed to be passed to new RegExp constructor then, with <rootDir> placeholder being replaced by actual path. By being used this way, \ character needs to be escaped twice - once as JavaScript string:
"\\"; // a backslash
"\"; // syntax error
And another time as regular expression:
/^[\\]$/.test("\\") // true
/^[\]$/.test("\\") // syntax error

problem with caret and dollar sign regex in nodejs

in node js when i try to check for validation of incoming string using express-validator it doesn't match using
check('firstName').matches('^[a-zA-Z\s\'\-$]')
to parse firstName of incoming request body
Note I've edited the question to be like
check('firstName').matches('^[a-zA-Z\s\'\-]$')
I see two issues here:
The range issue because of \-. You should use double escaping character instead.
The given regex will only match the first character because the quantifier is missing. You should use the + (one or more characters) quantifier at the end of the regex for full match.
The correct regex for your case would be:
check('firstName').matches('^[a-zA-Z\s\'\\-$]+')
express was treating the string in different way than /regex/ this was the issue.

Replacing string contains forward slashes in __filename in NodeJs

I'm using __filename variable in NodeJS ES7 and would like to replace file path
from
c:/web/google-web/tests/selenium/tests/desktop/main/login.js
to
c:/web/google-web/Results/desktop/main/login.log
I tried this code:
console.log(__filename.replace("tests/selenium/tests", "Results").replace('.js','.log'));
console.log(__filename.replace("tests\/selenium\/tests", "Results").replace('.js','.log'));
console.log(__filename.replace(/\//g, "-").replace("tests-selenium-tests", "Results").replace('.js','.log'));
I tried How to globally replace a forward slash in a JavaScript string? too but no luck.
If what you've tried isn't working I can only assume that __filename isn't what you expect it to be.
Your first two examples work just fine (the third doesn't switch hyphons back to slashes), and you can verify this by running:
"c:/web/google-web/tests/selenium/tests/desktop/main/login.js".replace("tests/selenium/tests", "Results").replace('.js','.log') === "c:/web/google-web/Results/desktop/main/lfghogin.log"; // true
Since your path starts c:/ I'm guessing you're on Windows? If so, you've got the slashes the wrong way round in your replacement.
If you want something generic to handle that then use .replace(/tests[\\/]selenium[\\/]tests/,'Results')

Variable amount of params express js

I am trying to define a route in express js that takes an unknown amount N of parameters. It should match the following routes, capturing all digit groups:
/scope
/scope/1/12
/scope/1/12/123
etc.
I wrote a regex for the matching of the n-amount of numbers, as follows:
/(?:\/?(\d+)\/?)/g
The global /g however doesn't seem to be allowed, see (The regex parser of express js on github). Am I doing something wrong here? I could solve this very ugly and dirty by doing something like:
^\/scope\/?(\d+)?\/?(\d+)?\/?(\d+)?
But this is not dynamic, feels dirty and if I add deeper levels of scoping I always will need to add more /?(\d+) regex parts, which is a model that does not fit my business logic. I am shure there must be a better way...
Okay, after a discussion with #vks, which was useful but unfortunately not answering the question, we came to the conclusion that this is not a regex problem. With the \g modifier a regex capturing all digit groups can quite easily be written, even in javascripts very limited regex engine.
The question now becomes more clearly formulated: since expressjs does not allow a full regex from begin to end, but rather encloses the regex you use in a route in it's own begin and end of a regex, not allowing /g modifiers, what is the expressjs idiomatic way to solve this problem?
^\/scope(?:\/\d+)*$
You can try this.See demo.
https://regex101.com/r/eZ0yP4/30

Routes in Symfony2

In some symfony2 project I have next definition of routes:
MyBundle_Default:
resource: "routing/default.yml"
prefix: /{slug}-{resource_id}
requirements:
slug: "[a-z\-]+"
resource_id: "\d+"
But this requirements don't work.
For example, if I have "-" in slug (e.g. "test-route") url like /test-route-9 do not work.
Is this a bug?
Mainly, I think your problem comes from the dash character. Let me explain. Say the url entered is /test-route-9. With your requirements, the slug matched would be test-route- because your regex states that is characters between a-z or the dash - that can be matched.
Regex will match every thing it can, so it will "eat" the dash character. By "eating" it, the rest would be only 9 which would not be correct because the routing expects another dash before matching the resource_id portion. Hence, this url wouldn't match as you expect.
Simple fix is to separate components with a / instead of dash, or change the character separating your slug to differentiate it from the url component separator.
Fix by changing separator in url:
prefix: /{slug}/{resource_id}
requirements:
slug: "[a-z\-]+"
resource_id: "\d+"
Or:
prefix: /{slug}_{resource_id}
requirements:
slug: "[a-z\-]+"
resource_id: "\d+"
Fix by changing separator for the slug directly:
prefix: /{slug}-{resource_id}
requirements:
slug: "[a-z_]+"
resource_id: "\d+"
I'm pretty sure the problem comes from this. Did not test anything, but worth a try just to be sure the problem lies with the dash character separator.
It's a typo, you put the requirement on hotel_id but define in the url resource_id!
Try with
slug: "[a-z\-]+(?<!-)"
This will make sure that the regex does NOT match the last dash, which is the problem as mentioned in Matts answer.
I hope it works for you :)
Looks like it was indeed a bug. At least in Symfony 3.4.36, all works as expected.

Resources