Regex matching to exclude beginning word - javascript

How can I make the following JavaScript
'id=d41c14fb-1d42&'.match(/(?![id=])(.*)[^&]/)[0]
return "d41c14fb-1d42"? It currently returns "41c14fb-1d42", without the beginning "d".

This should do it:
'id=d41c14fb-1d42&'.match(/^id=(.*)&$/)[1]
// "d41c14fb-1d42"
~ edit
When an original question does not give any context it is hard to guess what you need exactly, in which case I just give a solution that yields the requested output. I now understand you want to be able to parse a query string, i.e., name1=value1&name2=value2.... The following regular expression yields nameX followed by an optional =valueX, as I believe it is valid to provide just the parameter in a query string without a value.
var parameters = "id=foobar&empty&p1=javascript&p2=so".match(/\w+(=([^&]+))?/g)
// ["id=foobar", "empty", "p1=javascript", "p2=so"]
You can split on "=" to obtain parameter and value separately.
var param1 = parameters[0].split("=")
// ["id", "foobar"]
For a parameter without the value that would just yield an Array with 1 value, of course.
"empty".split("=") // ["empty"]
Note this assumes a query parameter to match \w+, if there are other cases you have to expand the regular expression.
If you only want to match the id parameter specifically anywhere in the query string and obtain its value, as I infer from your comment below, you can use:
"id=donald".match(/(?:^|&)id=([^&]+)/)[1]
// "donald"
"param1=value1&id=donald&param2=value2".match(/(?:^|&)id=([^&]+)/)[1]
// "donald"

Related

How to get content using filter and match?

I want to search in the array if theres the string that Im looking for, to do that im using match
const search_notes = array_notes.filter(notes => notes.real_content.toUpperCase().match(note.toUpperCase()));
as you can see, search_notes will give me an array with all the strings that at least has a character from the input or match completely, but theres a problem, because when I write , ), [], + or any regex symbol in the input it will gives me this error:
how can i solve this?
If you look at documentation for the match method (for instance, MDN's), you'll see that it accepts a RegExp object or a string, and if you give it a string, it passes that string into new RegExp. So naturally, characters that have special meaning in a regular expression need special treatment.
You don't need match, just includes, which doesn't do that:
const search_notes = array_notes.filter(
notes => notes.real_content.toUpperCase().includes(note.toUpperCase())
);

Empty value if regex match not found JavaScript

I'm attempting to extract any text characters at the beginning, and the following two numbers of a string. If the string starts with a number, I'd like to get an empty string value instead so the resulting array still contains 3 values.
String:
'M2.55X.45'
Code:
'M2.55X.45'.match(/(^[a-zA-Z]+)|((\.)?\d+[\/\d. ]*|\d)/g)
Expected:
["M", "2.55", ".45"]
Actual (correct):
["M", "2.55", ".45"]
String:
'2.55X.45'
Code:
'2.55X.45'.match(/(^[a-zA-Z]+)|((\.)?\d+[\/\d. ]*|\d)/g)
Expected:
["", "2.55", ".45"]
Actual:
["2.55", ".45"]
Use /^([a-zA-Z]?)(\d*(?:\.\d+)?)[a-zA-Z](\d*(?:\.\d+)?)$/.exec("2.55X.45") instead. This returns an array where the 1st element is the entire match, so you must access groups 1-indexed, for example, match[1] for the 1st value. You can try this out here.
Your current regex uses an alternate clause (|), which creates different types of grouping depending on which alternate is matched.
Here's an example (cleaned up a bit) that creates explicit groups and makes the individual groups optional.
const regex = /^([a-zA-Z]*)?(\d*(?:\.\d+)?)([a-zA-Z]+)(\d*(?:\.\d+)?)$/
console.log(regex.exec("2.55X.45"))
console.log(regex.exec("M2.55X.45"))
Note that I've removed the g flag, so the regex's state isn't preserved.
I've also used exec instead of match to not discard capture groups.
You can try this pattern
(\D*)(\d+(?:\.\d+))\D+(\.\d+)
let finder = (str) => {
return (str.match(/^(\D*)(\d+(?:\.\d+))\D+(\.\d+)/) || []).slice(1)
}
console.log(finder('M2.55X.45'))
console.log(finder("2.55X.45"))

Contents of a RegExp match

I've been trying to convert the following from Python to node.js. It's a simply program that uses regex to check if an IP address is Public or Private:
import re
def is_private_ip(ip):
"""
Returns `True` if the `ip` parameter is a private network address.
"""
c = re.compile('(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)')
if c.match(ip): return True
return False
print is_private_ip('192.168.0.1') # True
print is_private_ip('8.8.8.8') # False
print is_private_ip('109.231.231.221') # False
I implemented it in Javascript like this:
var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/);
console.log('192.168.0.1'.match(localIp));
console.log('8.8.8.8'.match(localIp));
console.log('109.231.231.221'.match(localIp));
Which gives me the following output:
[ '192.168.',
undefined,
undefined,
undefined,
undefined,
undefined,
'192.168.',
index: 0,
input: '192.168.0.1' ]
null
null
It seems to me like it works (not even sure tbh). The two IPs that should be public are returning null so I'm guessing that's right. I don't understand the output of the other match though? I've not been able to find out what it means
var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/);
console.log('192.168.0.1'.match(localIp));
gives you the output:
[ '192.168.',
undefined,
undefined,
undefined,
undefined,
undefined,
'192.168.']
That means:
'192.168.' that is the match of the regex on this string. the only one
undefined is the match for the first group in your regex: (^127\.0\.0\.1)
undefined for the group: (^10\.)
undefined for the group: (^172\.1[6-9]\.)
undefined for the group: (^172\.2[0-9]\.)
undefined for the group: (^172\.3[0-1]\.)
'192.168.' for the group: (^192\.168\.)
thats because of the parenthesis, each one of them giving a match (or undefined), plus the match that the match() function returns.
.match() gives you the number of matches possible in your String. Maybe what you're looking for is .test() method.
You need to modify the code like this:
var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/);
console.log(localIp.test('192.168.0.1'));
console.log(localIp.test('8.8.8.8'));
console.log(localIp.test('109.231.231.221'));
You may refer here for more details regarding the match method: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/match
You are using the String.prototype.match-method. According to the documentation, it returns "An Array containing the matched results or null if there were no matches."
In Javascript, an Array is truthy and null is falsy. This means that the following check would indeed correctly test if a string is a local IP:
if(someIpString.match(localIp)) {
// it is a local IP
}
else {
// it is not a local IP
}
What you are seeing in the array is the different parts of the original string that were matched by matching groups in the regular expression. The null values are the matches for groups that are not present, which you have plenty of.
But I think you can go a step further. If you want to simply check if a string matches the regular expression, I would recommend RegExp.prototype.test. This method returns a boolean (true|false), so you don't have to rely on truthy- or falsy-ness:
if(localIp.test(someIpString)) {
// it is a local IP
}
else {
// it is not a local IP
}
String.prototype.match():
If the regular expression does not include the g flag, returns the same result as RegExp.exec(). The returned Array has an extra input property, which contains the original string that was parsed. In addition, it has an index property, which represents the zero-based index of the match in the string.
RegExp.prototype.exec():
The returned array has the matched text as the first item, and then one item for each capturing parenthesis that matched containing the text that was captured.
If the match fails, the exec() method returns null.
Maybe you want to use RegExp.prototype.test() instead:
var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/);
console.log(localIp.test('192.168.0.1')); // => true
console.log(localIp.test('8.8.8.8')); // => false
console.log(localIp.test('109.231.231.221')); // => false
You don't need to use match groups, unless you want to capture the matching portion of the ip address, but that's not necessary in your case. In Javascript you can use this regex pattern (note no match groups):
var localIp = new RegExp(/^127\.0\.0\.1|^10\.|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168\./);
And then use it like this:
console.log('192.168.0.1'.match(localIp) != null);
console.log('8.8.8.8'.match(localIp) != null);
console.log('109.231.231.221'.match(localIp) != null);
Or, even better, use RegEx.test():
console.log(localIp.test('192.168.0.1'));
Similarly for Python, the match groups are not required.
One other thing worth noting is that your pattern will match invalid IP addresses, e.g. 10.bad.ip.address will be detected as a private IP address. Not a problem if are validating IP addresses elsewhere in your application, but you might want to tighten it up.

RegExp, JavaScript: Break string at specified characters, encode it, and insert it back in same position

I can't seem to find the correct JavaScript regular expression syntax to take a url string, get characters between other specified characters to encode, then insert back. My example may be easier to explain:
Example:
var url = 'http://www.myurl.com?t=23&dbUrl=http://www.encodeurl.com?t=23&otherUrl=http://www.anotherurl.com'
I need to grab the value between '&dbUrl=' and the next instance of 'http'. Take that value, 'encodeURIComponent' it, then insert it back into the var url to get:
http://www.myurl.com?t=23&dbUrl=http%3A%2F%2Fwww.encodeurl.com%3Ft%3D23%26otherUrl%3Dhttp://www.anotherurl.com
I tried splitting it at any instances of http and just encoding the [1]index of it but I don't always know when in the string '&dbUrl' will exist. I am not looking to break every query parameter but only alter the url between one query parameter and any instance of the next instance of 'http'. Only because the other query param, example used: '&otherUrl=' I wont know the exact query param so I wouldn't know when it stopped unless looking for the http. I will only know the query param of '&dbUrl='. Any ideas?
One approach would be to leverage the replace functionality to use a function as a second argument to return the transformed string. The return result of the function will end up as the replaced value in the original string,
url.replace(/(&dbUrl=)(.+)(?=http)/,
/*
m1 = first matched group
e.g, "&dbUrl=http://www.encodeurl.com?t=23&otherUrl="
m2 = second matched group
e.g, "&dbUrl="
m3 = third matched group
e.g, "http://www.encodeurl.com?t=23&otherUrl="
*/
function(m1, m2, m3) {
return m2 + encodeURIComponent(m3);
})
// returns,
// "http://www.myurl.com?t=23&dbUrl=http%3A%2F%2Fwww.encodeurl.com%3Ft%3D23%26otherUrl%3Dhttp://www.anotherurl.com"

Extract Fractional Number From String

I have a string that looks something like this
Hey this is my 1.20 string
I'm trying to just extract 1.20 from it.
What's the best way to do this?
I've tried something like this, but I get the value of 1.20,20 rather than just 1.20
var query = $(".query_time").html();
var matches = query.match(/\d.(\d+)/);
The result of the match function is an array, not a string. So simply take
var nb = query.match(/\d.(\d+)/)[0];
BTW, you should also escape the dot if you want to have more precise match :
var nb = query.match(/\d\.(\d+)/)[0];
or this if you want to accept commas (depends on the language) :
var nb = query.match(/\d[\.,](\d+)/)[0];
But the exact regex will be based on your exact needs, of course and to match any number (scientific notation ?) I'd suggest to have a look at more complex regex.
The value of matches is actually [ "1.20", "20" ] (which is an array). If you print it, it will get converted to a string, hence the 1.20,20.
String.match returns null or an array of matches where the first index is the fully matched part and then whichever parts you wanted. So the value you want is matches[0].
Try the following
var nb = query.match(/\d\.\d+/)[0]; // "1.20"
You need to escape . because that stands for any character.
Remove the capture group (\d+) and the second match is not returned
Add [0] index to retrieve the match

Categories

Resources