Apply two regex rules in match() - javascript

var url = document.referrer;
var a=document.createElement('a');
a.href=url;
var path = a.pathname;
Let's say path is this:
/cat-dog-fish/
I want to remove leading and trailing slashes, if they exist, else do nothing.
I can do this (removes trailing slash):
a.pathname.replace(/\/$/,'')
Or this (removes leading slash)
a.pathname.replace(/^\//,'')
But how do I remove both at once, in a oner, if they exist?

A regex literal like /^\/|\/$/g can be used to replace with empty string, or you may use /^\/([^]*)\// (match /, then any 0+ chars up to the last / capturing what is in-between the slashes) to replace with $1:
var s = "/cat-dog-fish/";
console.log(s.replace(/^\/|\/$/g, ''));
console.log(s.replace(/^\/([^]*)\/$/, '$1'));
Note:
^\/ - matches the start of string and a / right there
| - means OR
\/$ - matches a / at the end of string
([^]*) - is a capturing group (...) that captures 0 or more (*) any characters as [^] means not nothing.

var a="/cat-dog-fish/";
var d = a.replace(new RegExp("(^\/|\/$)",'g'),'');
console.log(d);
a.pathname.replace(new RegExp("(^\/|\/$)",'g'),'');

Related

Regex between last two characters

I have a querstion about simple regex. I need to get between of these characters: - and ~
My string: Champions tour - To Win1 - To Win2 ~JIM FURYK
When I use this: \-([^)]+\~) it is giving as matched this:
To Win1 - To Win2 ~
But I need this:
To Win2 ~JIM FURYK
Is it possible to this?
My regex is here: https://regex101.com/r/fJBLXb/1/
Just add \-([^-)]+\~) - dash to not match
Your \-([^)]+\~) regex matches the leftmost - that is directly followed with one or more chars other than ) (so it matches -, a, §, etc.) and then a ~ char. It does not stop at - chars and thus can match any amount of hyphens.
To match the value after last hyphen you can use
[^\s-][^-]*$
See the regex demo and the regex graph. Details:
[^\s-] - a char other than whitespace and -
[^-]* - zero or more chars other than -
$ - end of string.
See the JavaScript demo:
const text = 'Champions tour - To Win1 - To Win2 ~JIM FURYK';
const match = text.match(/[^\s-][^-]*$/);
if (match) {
console.log(match[0]);
}
You could use match as follows:
var input = "Champions tour - To Win1 - To Win2 ~JIM FURYK";
var output = input.match(/- ([^-]+~.*)$/)[1];
console.log(output);
The regex pattern used above says to match:
- a hyphen
[ ] a single space
( capture what follows
[^-]+ match all content WITHOUT crossing another hyphen
~ ~
.* all remaining content
) stop capture
$ end of the string

Javascript Regex: Capture between two asterisks with multiple asterisks in comma delimited string

I am trying to capture all characters between multiple instances of asterisks, which are comma delimited in a string. Here's an example of the string:
checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*
The caveat is that the phrase must start and end with an asterisk. I have been able to come close by using the following regex, however, it won't discard any matches when the captured string is missing the starting asterisk(*):
let str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*"
const regex = /[^\,\*]+(?=\*)/gi;
var a = str.match(regex)
console.log(a) // answer should exclude checkboxID0 and checkboxID5
The answer returns the following, however, "checkboxID0 and checkboxID5" should be excluded as it doesn't start with an asterisk.
[
"checkboxID0",
"checkboxID1",
"checkboxID3",
"checkboxID5"
]
Thanks, in advance!
You need to use asterisks on both ends of the pattern and capture all 1 or more chars other than commas and asterisks in between:
/\*([^,*]+)\*/g
See the regex demo
Pattern details
\* - an asterisk
([^,*]+) - Capturing group 1: one or more chars other than , and *
\* - an asterisk
JS demo:
var regex = /\*([^,*]+)\*/g;
var str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*";
var m, res = [];
while (m = regex.exec(str)) {
res.push(m[1]);
}
console.log(res);

exec from regex returns null

This is my code snippet:
var myString = '#EXTINF:-1 group-title="|FR| CHAINES FRANÇAISES |FR|",|FR|*****CANALSAT*****|FR|';
var group_title = /(group-title=")(\S*)["]/;
var matchgroup_title = group_title.exec(myString);
console.log(matchgroup_title);
I am not familiar to regex so I can't understand this code. Why does exec here return null?
The problem exists because of \S*. If you pop it into regex101.com, you'll see:
So, \s* will match any non-whitespace character, and a space is considered a whitespace character, so this does not match. You can simply use [^"] to check for anything that isn't another quote.
You can simplify this to:
var myString = '#EXTINF:-1 group-title="|FR| CHAINES FRANÇAISES |FR|",|FR|*****CANALSAT*****|FR|';
var group_title = /group-title="([^"]+)"/;
var matchgroup_title = group_title.exec(myString);
console.log(matchgroup_title);
(group-title=") matches group-title="
(\S*) matches zero or more non-whitespace characters, so |FR|
["] then matches a ", but there isn't one (well, there is, but there are whitespace characters first, so no match).

How to use a variable inside Regex?

I have this line in my loop:
var regex1 = new RegExp('' + myClass + '[:*].*');
var rule1 = string.match(regex1)
Where "string" is a string of class selectors, for example: .hb-border-top:before, .hb-border-left
and "myClass" is a class: .hb-border-top
As I cycle through strings, i need to match strings that have "myClass" in them, including :before and :hover but not including things like hb-border-top2.
My idea for this regex is to match hb-border-top and then :* to match none or more colons and then the rest of the string.
I need to match:
.hb-fill-top::before
.hb-fill-top:hover::before
.hb-fill-top
.hb-fill-top:hover
but the above returns only:
.hb-fill-top::before
.hb-fill-top:hover::before
.hb-fill-top:hover
and doesn't return .hb-fill-top itself.
So, it has to match .hb-fill-top itself and then anything that follows as long as it starts with :
EDIT:
Picture below: my strings are the contents of {selectorText}.
A string is either a single class or a class with a pseudo element, or a rule with few clases in it, divided by commas.
each string that contains .hb-fill-top ONLY or .hb-fill-top: + something (hover, after, etc) has to be selected. Class is gonna be in variable "myClass" hence my issue as I can't be too precise.
I understand you want to get any CSS selector name that contains the value anywhere inside and has EITHER : and 0+ chars up to the end of string OR finish right there.
Then, to get matches for the .hb-fill-top value you need a solution like
/\.hb-fill-top(?::.*)?$/
and the following JS code to make it all work:
var key = ".hb-fill-top";
var rx = RegExp(key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "(?::.*)?$");
var ss = ["something.hb-fill-top::before","something2.hb-fill-top:hover::before","something3.hb-fill-top",".hb-fill-top:hover",".hb-fill-top2:hover",".hb-fill-top-2:hover",".hb-fill-top-bg-br"];
var res = ss.filter(x => rx.test(x));
console.log(res);
Note that .replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') code is necessary to escape the . that is a special regex metacharacter that matches any char but a line break char. See Is there a RegExp.escape function in Javascript?.
The ^ matches the start of a string.
(?::.*)?$ will match:
(?::.*)?$ - an optional (due to the last ? quantifier that matches 1 or 0 occurrences of the quantified subpattern) sequence ((?:...)? is a non-capturing group) of a
: - a colon
.* - any 0+ chars other than line break chars
$ - end of the string.
var regex1 = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`)
var passes = [
'.hb-fill-top::before',
'.hb-fill-top:hover::before',
'.hb-fill-top',
'.hb-fill-top:hover',
'.hb-fill-top::before',
'.hb-fill-top:hover::before',
'.hb-fill-top:hover'
];
var fails = ['.hb-fill-top-bg-br'];
var myClass = '.hb-fill-top';
var regex = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`);
passes.forEach(p => console.log(regex.test(p)));
console.log('---');
fails.forEach(f => console.log(regex.test(f)));
var regex1 = new RegExp('\\' + myClass + '(?::[^\s]*)?');
var rule1 = string.match(regex1)
This regex select my class, and everething after if it start with : and stop when it meets a whitespace character.
See the regex in action.
Notice also that I added '\\' at the beginning. This is in order to escape the dot in your className. Otherwise it would have matched something else like
ahb-fill-top
.some-other-hb-fill-top
Also be careful about .* it may match something else after (I don't know your set of strings). You might want to be more precise with :{1,2}[\w-()]+ in the last group. So:
var regex1 = new RegExp('\\' + myClass + '(?::{1,2}[\w-()]+)?');

RegExp match word till space or character

I'm trying to match all the words starting with # and words between 2 # (see example)
var str = "#The test# rain in #SPAIN stays mainly in the #plain";
var res = str.match(/(#)[^\s]+/gi);
The result will be ["#The", "#SPAIN", "#plain"] but it should be ["#The test#", "#SPAIN", "#plain"]
Extra: would be nice if the result would be without the #.
Does anyone has a solution for this?
You can use
/#\w+(?:(?: +\w+)*#)?/g
See the demo here
The regex matches:
# - a hash symbol
\w+ - one or more alphanumeric and underscore characters
(?:(?: +\w+)*#)? - one or zero occurrence of:
(?: +\w+)* - zero or more occurrences of one or more spaces followed with one or more word characters followed with
# - a hash symbol
NOTE: If there can be characters other than word characters (those in the [A-Za-z0-9_] range), you can replace \w with [^ #]:
/#[^ #]+(?:(?: +[^ #]+)*#)?/g
See another demo
var re = /#[^ #]+(?:(?: +[^ #]+)*#)?/g;
var str = '#The test-mode# rain in #SPAIN stays mainly in the #plain #SPAIN has #the test# and more #here';
var m = str.match(re);
if (m) {
// Using ES6 Arrow functions
m = m.map(s => s.replace(/#$/g, ''));
// ES5 Equivalent
/*m = m.map(function(s) {
return s.replace(/#$/g, '');
});*/ // getting rid of the trailing #
document.body.innerHTML = "<pre>" + JSON.stringify(m, 0, 4) + "</pre>";
}
You can also try this regex.
#(?:\b[\s\S]*?\b#|\w+)
(?: opens a non capture group for alternation
\b matches a word boundary
\w matches a word character
[\s\S] matches any character
See demo at regex101 (use with g global flag)

Categories