Regex pattern failing valid strings using Mongo json schema - javascript

I am trying to add a schema to one of my Mongo DB collections. One field should be guarded by the following regex pattern:
^rgba[(][0-9]+, [0-9]+, [0-9]+, (0([.][0-9]+)?|1([.]0+)?)[)]$
This regex expression successfully passes correctly structured strings such as rgba(0, 0, 0, 1) using Node.js. Unfortunately, when using the same regex in my json schema it seems to not match any strings. The schema for the specific field:
textColor: {
bsonType: "string",
pattern: "^rgba[(][0-9]+, [0-9]+, [0-9]+, (0([.][0-9]+)?|1([.]0+)?)[)]$"
}
Is there anything inside of the regex string that should be escaped to make it work? How can I rewrite this to make it work?

I found the issue. It was unrelated to the regex expression. The update for the schema was not added properly to the collection. Which was an error on my side of things and unrelated to MongoDB at all. The regex did actually end up working.

Related

How to "black list" pages with a query string parameter

I am using cookieconsent.js to show a popup for users to accept for my website. I need to stop the cookie consent popup from showing if a page has a certain query string.
The documentation for cookieconsent provides a solution to "blacklistPage" where I can "Specify pages using string or RegExp" that I want to prevent the popup from showing on.
This is fine until I try to use regex for a query string.
Example of path, filename and query string to match:
/sub-folder/file-name.shtml?value=pair
"blacklistPage": [
"/.*\?value=pair"
]
According to the documentation it's expecting either regex or a string but you're trying to pass regex in a string which isn't valid.
using a string : ‘/index.html’ (matches ‘/index.html’ exactly)
using RegExp : /\/page_[\d]+.html/ (matched ‘/page_1.html’ and ‘/page_2.html’ etc)
Additionally you're quoting the blacklistPage, this doesn't need to be quoted.
By removing the quotes and provide a standard JS regex format you can make the following:
blacklistPage: [
/\/.*\?value=pair/
]
Alternatively your use case is simple so you could just use a string and avoid regex:
blacklistPage: [
'/sub-folder/file-name.shtml?value=pair'
]
I have come to the conclusion, along with a friend who knows js much better than I, that the cookieconsent.js script will not allow query strings.

Javascript str.split(/[^a-zA-Z0-9.#]|(username|fname)/ not removing 'username' or 'fname' from string

I have a simple query string in my program:
?username=someone#email.com&fname=
I have come up with a regular expression that selects everything except the data I want:
[^a-zA-Z0-9.#]|(username|fname)
I am trying to use javascripts str.split() to split around everything that isn't actually data in the query, like so:
let userinfo = global.location.search.split(/[^a-zA-Z0-9.#]|(username|fname)/).filter(Boolean);
Unfortunately, when this runs, I get the following array:
['username', 'someone#email.com', 'fname'].
I expect just ['someone#email.com'] since "username" and "fname" should be split around from my regex.
I have tested this in https://regex101.com/ and it appears to work fine, so I'm not sure why it doesn't work in JS.
Any ideas?
When you have a capture group in the regexp used with .split() the captured strings are included in the resulting array.
If you need a group but don't want to include it in the result, use a non-capturing group (?:username|fname).
But there's no need for the group in this case at all. /xxx|(yyy|zzz)/ matches the same thing as /xxx|yyy|zzz/, they only differ in what they capture.
/[^a-zA-Z0-9.#]|username|fname/
You need Regex for such tasks, you can use standard URLSearchParams API
let searchParams = "?username=someone#email.com&fname="
let parsed = new URLSearchParams(searchParams)
console.log(parsed.get('username'))

Regular expression word to match text that includes a word ending in 'ing' but does exclude the words anything, something, nothing

I am coding an app to practice English, I need a javascript regular expression to find all the docs in a mongoDb collection on which the 'answer' property contains a word that ends in ing and exclude a few words from the match like everything, something, anything, nothing.
I have the following query right now:
{ '$or': [ { answer: /ing/i } ],
I20190303-13:26:00.915(-4)? answer: /^(?!.*(\bsomething\b|\banything\b|\beverything\b|\bthing\b|\bnothing\b))/gi }
Unfortunately, my current query excludes strings like: 'I am doing nothing.' because nothing is in the text. But I would like texts like this to match because doing is present.
I want to get all the questions from the database whose answer contains one or more gerunds, unfortunately there are words that end in ing that are not gerunds.
Negative Lookbehind should work.
db.collection.find({
"key": {
$regex: "(?<!noth|anyth)ing", //match ing, but not if it is part of nothing, anything
$options: "i"
}
})
Demo
You can use the following regular expression to find all documents in a MongoDB collection where the 'answer' property contains a word that ends in "ing" and exclude a few words like "everything", "som
/\b(?!(everything|something|anything|nothing)\b)\w+ing\b/gi
I hope this will solve your problem.

$regex match pattern has different result in MongoDB vs. Javascript

I am using this $regex pattern in a mongo query:
{domain: {$regex: '^(.+\.)?youtube.com$'}}
Expecting it to match youtube.com, and sub.youtube.com.
The problem I'm seeing is that it's matching things like justyoutube.com.
In JavaScript, it does not match:
console.log(/^(.+\.)?youtube.com$/.test('justyoutube.com'));
// this returns `false` as expected.
Is there some better way to get this working? And is the issue with my regex, or the regex library used by MongoDB?
Update: looks like when I use /pattern/ vs. 'pattern' i get the results I'm expecting. Still curious how to get it using quotes since I could debug easier in MongoDB Compass.
I'm guessing the \ in the string you pass is acting as an escape character in the string itself, and doesn't make it into the actual regex. You can try doubling the backslash to sort of 'escape the escape':
const unescaped = new RegExp('^(.+\.)?youtube.com$')
const escaped = new RegExp('^(.+\\.)?youtube.com$')
console.log(unescaped.test('justyoutube.com'));
console.log(escaped.test('justyoutube.com'));
console.log(unescaped.test('sub.youtube.com'));
console.log(escaped.test('sub.youtube.com'));
// Or you can use a template literal, which interprents all its characters literally:
const withBacktick = new RegExp(`^(.+\.)?youtube.com$`);
console.log(withBacktick.test('sub.youtube.com'));
console.log(withBacktick.test('justyoutube.com'));

Partial Regexp Match in Javascript

I have a long regex that is generated to match URLs like
/^\/([^\/.?]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?$/
Would match:
/foo/bar/1.html
as ['foo', 'bar', '1', 'html']
In Javascript I would like to get the parts that match as the user types the url (like a typeahead). For example if they typed:
/foo
It would tell me that /foo was matched, but the whole regexp hasn't been satisfied. Ruby can return an array with only the matching partial elements like : ['foo', nil, nil, nil] is this possible, or easy to do in Javascript?
#minitech basically gave half the answer: use ? after each group, and then you'll be able to match the regex even if they're missing. Once you can do that, then just check the groups of the regex result to see which bits have been matched and which haven't.
For example:
/^\/([^\/.?]+)?(?:\/([^\/.?]+)?(?:\/([^\/.?]+)?(?:\.([^\/.?]+))?)?)?$/.exec('/ab/c')
Would return:
["/ab:c", "ab:c", "c", undefined, undefined]
By checking and seeing that the fourth value returned is undefined, you could then figure out which chunks were/were not entered.
As a side note, if you're going to be working lots of regexs like this, you can easily lose your sanity just trying to keep track of which group is which. For this reason I strongly recommend using "named group" regular expressions. These are otherwise normal regular expressions that you can create if you use the XRegxp library (http://xregexp.com/), like so:
var result = XRegExp.exec('/ab/c', /^\/(?<fooPart>[^\/.?]+)?(?<barPart>?:\/([^\/.?]+)?(?:\/([^\/.?]+)?(?:\.([^\/.?]+))?)?)?$/)
var fooPart = result.fooPart
That library also has other handy features like comments that can similarly help keep regular expression under control. If you're only using this one regex it's probably overkill, but if you're doing lots of JS regexp work I can't recommend that library enough.

Categories