How to get the 1st character after a pattern using regex? - javascript

I'm trying to get the first character after the pattern.
i.e.
border-top-color
padding-top
/-[a-z]/g
selects:
border[-t]op[-c]olor
padding[-t]op
I want to select:
border-[t]op-[c]olor
padding-[t]op
How do you just get the first character after a selected pattern?
Example Here! :)

To get the t after border-, you usally match with this kind of regex:
border-(.)
You can then extract the submatch:
var characterAfter = str.match(/border-(.)/)[1];
match returns an array with the whole match as first element, and the submatches in the following positions.
To get an array of all the caracters following a dash, use
var charactersAfter = str.match(/-(.)/g).map(function(s){ return s.slice(1) })

Just use a capturing group:
"border-top-color".replace(/-([a-z])/g, "-[$1]")
Result:
"border-[t]op-[c]olor"

You can use submatching like dystroy said or simply use lookbehind to match it:
/(?<=-)./

Related

How to extract specific substring from a string using a one liner

Input: parent/123/child/grand-child
Expected output: child
Attempt 1: (?<=\/parent\/\d*)(.*)(?=\/.*)
Error: A quantifier inside a lookbehind makes it non-fixed width, look behind does not accept * but I don't know the width of the number hence must use it
Attempt 2: (works but 2 liners):
const currentRoute='/parent/123/child/grand-child'
let extract = currentRoute.replace(/\/parent\/\d*/g, '');
extract = extract.substring(1, extract.lastIndexOf('/'));
console.log('Result', extract)
How do I get the extract with a one liner, preferably using regex
Your current pattern will match 123/child instead of child only as there is a forward slash missing after \d* (note the * means 0 or more times)
It will also over match (See demo) due to the .* if there are more forward slashes present.
Instead, you could make use of a capturing group and use match.
parent\/\d+\/(\w+)\/
Regex demo
The value is in capturing group 1.
let res = "parent/123/child/grand-child".match(/parent\/\d+\/(\w+)\//);
if (res) console.log(res[1])
A pattern with a lookbehind to get the value child could be
(?<=parent\/\d*\/)([^\/]+)(?=\/)
Regex demo
Note that this is not yet widely supported.
let res = "parent/123/child/grand-child".match(/(?<=parent\/\d*\/)([^\/]+)(?=\/)/);
if (res) console.log(res[0])
How about
currentRoute.match(/\/parent\/(?:.*)\/(.*)\//)[1]
If the format is fixed, then use .split("/")[2] to get 3rd element
console.log(currentRoute.split("/")[2]);
"child"
To match the parent part of the string use .match(/^parent\/[^\/]+\/([^\/]+)/)[1]
console.log(currentRoute.match(/^parent\/[^\/]+\/([^\/]+)/)[1]);
"child"

Splitting a String with Emoji Regex Respecting Variation Selector 15

I'm trying to create a way to split a string by emoji and non-emoji chunks. I managed to get a regex from here and altered to this to take into account the textual variation selector:
(?:(?!(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+\ufe0e))(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+
This works with .match such as:
'🇦🇨'.match(regex) // (["0x1F1E6", "0x1F1E8"]) => ['🇦🇨']
'🇦🇨'.match(regex) // (["0x1F1E6", "0x1F1E8", "0xFE0E]) => null
But split isn't giving me the expected results:
'🇦🇨'.split(regex) // (["", undefined, "🇨", ""]) => ['🇦🇨']
I need split to return the entire emoji in one element. What am I doing wrong?
EDIT:
I have a working regex now, except for the edge case exhibited here: https://regex101.com/r/Vki2ZS/2.
I don't want the second emoji to be matched since it is succeeded by the textual variant selector. I think this is because I'm using lookahead, as the reverse string is matched as expected, but I can't use negative look behind since it's not supported by all browsers.
Your pattern does not work because the second emoji got partly matched with the + quantified (?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+: \uD83E\uDD20\uFE0F\uD83E\uDD20 was matched in \uD83E\uDD20\uFE0F\uD83E\uDD20\uFE0E with two iterations, first \uD83E\uDD20\uFE0F, then \uD83E\uDD20.
The pattern you may use with .split is
/((?:(?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(?!\ufe0e)(?:\ufe0f)?(?:\u200d)?)+)/
The main goal was to fail all matches where (?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+ was followed with \uFE0E, see I added a negative lookahead (?!\ufe0e).
JS demo:
var regex = /((?:(?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(?!\ufe0e)(?:\ufe0f)?(?:\u200d)?)+)/;
console.log('🇦🇨'.split(regex));
console.log('🤠️🤠︎'.split(regex));
// If you need to wrap the match with some tags:
console.log('🤠️🤠︎'.replace(/(?:(?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(?!\ufe0e)(?:\ufe0f)?(?:\u200d)?)+/g, '<span class="special">$&</span>'))

Javascript Regex - Get All string that has square brackets []

I have string data below:
var data = "somestring[a=0]what[b-c=twelve]----[def=one-2]test"
I need to get all strings that contain square brackets []. This is the result that I want.
["[a=0]", "[b-c=twelve]", "[def=one-2]"]
I've tried using regex /\[(.*?)\]/, but what I've got is an only the first array element is correct, the next elements are basically the same value but without the square brackets.
data.match(/\[(.*?)\]/);
// result => ["[a=0]", "a=0"]
What regexp should I use to achieve the result that I want? Thank you in advance.
You want to use the g (global) modifier to find all matches. Since the brackets are included in the match result you don't need to use a capturing group and I used negation instead to eliminate the amount of backtracking.
someVar.match(/\[[^\]]*]/g);
In /\[(.*?)\]/, *? means lazy, matching as few content as possible.
What you actually want is all the matches in content. Try modifier g
Try this one, http://regex101.com/r/aD6cM8/1. Any match starts with [, ends with ], but doesn't allow[ or ] inbetween.
someVar.match(/\[([^\[\]]*)\]/g)
You should just add the g switch to your regex :
someVar.match(/\[(.*?)\]/); // result => ["[a=0]", "a=0"]
results in
[ "[a=0]", "[b-c=twelve]", "[def=one-2]" ]
Your regex is correct, just suffix g to it to make it global:
someVar.match(/\[(.*?)\]/g);
Here's more info on it: http://www.w3schools.com/jsref/jsref_regexp_g.asp

Matching everything after first pipe character in Javascript RegEx

I have this string:
"http://www.yahoo.com/abc/123|X|Y|Z"
I need to get everything after the first pipe with a regex. So I would want to be left with this string:
"X|Y|Z"
How do I do this in JavaScript?
Using a simpler regex /\|(.*)/
var str = "http://www.yahoo.com/abc/123|X|Y|Z";
var aryMatches = str.match(/\|(.*)/);
// aryMatches[1] will have your results
regex explaination
Converting my comment to an answer:
Shockingly, regexes are not the answer to everything.
> xkcd
Try this:
str.split("|").slice(1).join("|");
This splits your string on pipe characters, slices off the first item, then joins the rest with pipes again.
First group contains the expected characters,
^.*?\|(.*)$
DEMO
You can use this regex:
/^[^|]*\|(.*)/
And use matched group #1 for your match.
Forget the splitting and splicing, just use a substring
var str = "http://www.yahoo.com/abc/123|X|Y|Z";
str.substr(str.indexOf("|") + 1);

Extract specific chars from a string using a regex

I need to split an email address and take out the first character and the first character after the '#'
I can do this as follows:
'bar#foo'.split('#').map(function(a){ return a.charAt(0); }).join('')
--> bf
Now I was wondering if it can be done using a regex match, something like this
'bar#foo'.match(/^(\w).*?#(\w)/).join('')
--> bar#fbf
Not really what I want, but I'm sure I miss something here! Any suggestions ?
Why use a regex for this? just use indexOf to get the char at any given position:
var addr = 'foo#bar';
console.log(addr[0], addr[addr.indexOf('#')+1])
To ensure your code works on all browsers, you might want to use charAt instead of []:
console.log(addr.charAt(0), addr.charAt(addr.indexOf('#')+1));
Either way, It'll work just fine, and This is undeniably the fastest approach
If you are going to persist, and choose a regex, then you should realize that the match method returns an array containing 3 strings, in your case:
/^(\w).*?#(\w)/
["the whole match",//start of string + first char + .*?# + first string after #
"groupw 1 \w",//first char
"group 2 \w"//first char after #
]
So addr.match(/^(\w).*?#(\w)/).slice(1).join('') is probably what you want.
If I understand correctly, you are quite close. Just don't join everything returned by match because the first element is the entire matched string.
'bar#foo'.match(/^(\w).*?#(\w)/).splice(1).join('')
--> bf
Using regex:
matched="",
'abc#xyz'.replace(/(?:^|#)(\w)/g, function($0, $1) { matched += $1; return $0; });
console.log(matched);
// ax
The regex match function returns an array of all matches, where the first one is the 'full text' of the match, followed by every sub-group. In your case, it returns this:
bar#f
b
f
To get rid of the first item (the full match), use slice:
'bar#foo'.match(/^(\w).*?#(\w)/).slice(1).join('\r')
Use String.prototype.replace with regular expression:
'bar#foo'.replace(/^(\w).*#(\w).*$/, '$1$2'); // "bf"
Or using RegEx
^([a-zA-Z0-9])[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+#([a-zA-Z0-9-])[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$
Fiddle

Categories

Resources