RegEx Split String and Leave Delimiter - javascript

I am trying to split a string and leave the delimiter intact. I am getting pretty close but I can't figure it out fully. I have found a lot of examples on Stack Overflow but I am still running in to an issue that I can't figure out. Here is the code:
"This is a string with ${G:VarSome:G} text".split(/\$\{(.+?(}\(.+?\)|}))/g)
The above code yields:
['This is a string with ', 'G:VarSome:G}', '}', ' text']
The result I am looking for is:
['This is a string with ', '${G:VarSome:G}', ' text']
The ${G:SomeVar:G} pattern is a templating system where variables will be injected. There are other formats of variables too for example ${G:AnotherVar:1}, ${G:DifferentVar:5} etc. After I get the split string, I will do a variable lookup in the system to inject the corresponding variable.

You are having an extra capture group inside the regex, this will give you a single group.
const result = "This is a string with ${G:VarSome:G} text".split(/(\${.+?})/g);
console.log(result);
The regex that graps a single capture group looks like this. it returns all the captured inside ()
/(\${.+?})/g
This should capture the examples provided. regex101
It's build with first getting
${ and then getting one or more characters lazily (.+?) until it encounters a }.

You can use this regex for splitting:
/(\${[^}]*})/
Code:
var s = 'This is a string with ${G:VarSome:G} text';
var arr = s.split(/(\${[^}]*})/);
console.log(arr);
Here:
\${[^}]*}: Will match ${ followed by 0 or more non-} characters followed by }

Related

Extract content of code which start with a curly bracket and ends with a curly bracket followed by closing parenthesis

I'm completely mess with Regular Expressions right now(lack of practice).
I'm writing a node script, which goes through a bunch of js files, each file calls a function, with one of the arguments being a json. The aim is to get all those json arguments and place them in one file. The problem I'm facing at the moment is the extraction of the argument part of the code, here is the function call part of that string:
$translateProvider.translations('de', {
WASTE_MANAGEMENT: 'Abfallmanagement',
WASTE_TYPE_LIST: 'Abfallarten',
WASTE_ENTRY_LIST: 'Abfalleinträge',
WASTE_TYPE: 'Abfallart',
TREATMENT_TYPE: 'Behandlungsart',
TREATMENT_TYPE_STATUS: 'Status Behandlungsart',
DUPLICATED_TREATMENT_TYPE: 'Doppelte Behandlungsart',
TREATMENT_TYPE_LIST: 'Behandlungsarten',
TREATMENT_TARGET_LIST: 'Ziele Behandlungsarten',
TREATMENT_TARGET_ADD: 'Ziel Behandlungsart hinzufügen',
SITE_TARGET: 'Gebäudeziel',
WASTE_TREATMENT_TYPES: 'Abfallbehandlungsarten',
WASTE_TREATMENT_TARGETS: '{{Abfallbehandlungsziele}}',
WASTE_TREATMENT_TYPES_LIST: '{{Abfallbehandlungsarten}}',
WASTE_TYPE_ADD: 'Abfallart hinzufügen',
UNIT_ADD: 'Einheit hinzufügen'
})
So I'm trying to write a regular expression which matches the segment of the js code, which starts with "'de', {" and ends with "})", while it can have any characters between(single/double curly brackets included).
I tried something like this \'de'\s*,\s*{([^}]*)})\ , but that doesn't work. The furthest I got was with this \'de'\s*,\s*{([^})]*)}\ , but this ends at the first closing curly bracket within the json, which is not what I want.
It seems, that even the concepts of regular exressions I understood before, now I completely forgot.
Any is help is much appreciated.
You did not state the desired output. Here is a solution that parses the text, and creates an array of arrays. You can easily transform that to a desired output.
const input = `$translateProvider.translations('de', {
WASTE_MANAGEMENT: 'Abfallmanagement',
WASTE_TYPE_LIST: 'Abfallarten',
WASTE_ENTRY_LIST: 'Abfalleinträge',
WASTE_TYPE: 'Abfallart',
TREATMENT_TYPE: 'Behandlungsart',
TREATMENT_TYPE_STATUS: 'Status Behandlungsart',
DUPLICATED_TREATMENT_TYPE: 'Doppelte Behandlungsart',
TREATMENT_TYPE_LIST: 'Behandlungsarten',
TREATMENT_TARGET_LIST: 'Ziele Behandlungsarten',
TREATMENT_TARGET_ADD: 'Ziel Behandlungsart hinzufügen',
SITE_TARGET: 'Gebäudeziel',
WASTE_TREATMENT_TYPES: 'Abfallbehandlungsarten',
WASTE_TREATMENT_TARGETS: '{{Abfallbehandlungsziele}}',
WASTE_TREATMENT_TYPES_LIST: '{{Abfallbehandlungsarten}}',
WASTE_TYPE_ADD: 'Abfallart hinzufügen',
UNIT_ADD: 'Einheit hinzufügen'
})`;
const regex1 = /\.translations\([^{]*\{\s+(.*?)\s*\}\)/s;
const regex2 = /',[\r\n]+\s*/;
const regex3 = /: +'/;
let result = [];
let m = input.match(regex1);
if(m) {
result = m[1].split(regex2).map(line => line.split(regex3));
}
console.log(result);
Explanation of regex1:
\.translations\( -- literal .translations(
[^{]* -- anything not {
\{\s+ -- { and all whitespace
(.*?) -- capture group 1 with non-greedy scan up to:
\s*\}\) -- whitespace, followed by })
s flag to make . match newlines
Explanation of regex2:
',[\r\n]+\s* -- ',, followed by newlines and space (to split lines)
Explanation of regex3:
: +' -- literal : ' (to split key/value)
Learn more about regex: https://twiki.org/cgi-bin/view/Codev/TWikiPresentation2018x10x14Regex
This can be done with lookahead, lookbehind, and boundary-type assertions:
/(?<=^\$translateProvider\.translations\('de', {)[\s\S]*(?=}\)$)/
(?<=^\$translateProvider\.translations\('de', {) is a lookbehind assertion that checks for '$translateProvider.translations('de', {' at the beginning of the string.
(?=}\)$) is a lookahead assertion that checks for '})' at the end of the string.
[\s\S]* is a character class that matches any sequence of space and non-space characters between the two assertions.
Here is the regex101 link for you to test
Hope this helps.

Extracting a complicated part of the string with plain Javascript

I have a following string:
Text
I want to extract from this string, with the use of JavaScript 'pl' or 'pl_company_com'
There are a few variables:
jan_kowalski is a name and surname it can change, and sometimes even have 3 elements
the country code (in this example 'pl') will change to other en / de / fr (this is that part of the string i want to get)
the rest of the string remains the same for every case (beginning + everything after starting with _company_com ...
Ps. I tried to do it with split, but my knowledge of JS is very basic and I cant get what i want, plase help
An alternative to Randy Casburn's solution using regex
let out = new URL('https://my.domain.com/personal/jan_kowalski_pl_company_com/Documents/Forms/All.aspx').href.match('.*_(.*_company_com)')[1];
console.log(out);
Or if you want to just get that string with those country codes you specified
let out = new URL('https://my.domain.com/personal/jan_kowalski_pl_company_com/Documents/Forms/All.aspx').href.match('.*_((en|de|fr|pl)_company_com)')[1];
console.log(out);
let out = new URL('https://my.domain.com/personal/jan_kowalski_pl_company_com/Documents/Forms/All.aspx').href.match('.*_((en|de|fr|pl)_company_com)')[1];
console.log(out);
A proof of concept that this solution also works for other combinations
let urls = [
new URL('https://my.domain.com/personal/jan_kowalski_pl_company_com/Documents/Forms/All.aspx'),
new URL('https://my.domain.com/personal/firstname_middlename_lastname_pl_company_com/Documents/Forms/All.aspx')
]
urls.forEach(url => console.log(url.href.match('.*_(en|de|fr|pl).*')[1]))
I have been very successful before with this kind of problems with regular expressions:
var string = 'Text';
var regExp = /([\w]{2})_company_com/;
find = string.match(regExp);
console.log(find); // array with found matches
console.log(find[1]); // first group of regexp = country code
First you got your given string. Second you have a regular expression, which is marked with two slashes at the beginning and at the end. A regular expression is mostly used for string searches (you can even replace complicated text in all major editors with it, which can be VERY useful).
In this case here it matches exactly two word characters [\w]{2} followed directly by _company_com (\w indicates a word character, the [] group all wanted character types, here only word characters, and the {}indicate the number of characters to be found). Now to find the wanted part string.match(regExp) has to be called to get all captured findings. It returns an array with the whole captured string followed by all capture groups within the regExp (which are denoted by ()). So in this case you get the country code with find[1], which is the first and only capture group of the regular expression.

Regular Express for Javascript - Contain a specific word in the beginning after get any character until a certain character comes

I need a certain type of regular expression where I need list of special type of strings from a string. Example input:
str = 'this is extra data which i do not need /type/123456/weqweqweqweqw/ these are more extra data which i dont need /'
Result needed:
/type/123456/weqweqweqweqw/
Here the /type/ string will be constant and the remaining will be dynamic i.e. 123456/weqweqweqweqw and the last string will be /.
I tried:
var myRe = /\/type\/(.*)\//g
But this matches everything from /type/ to the end of the string.
Instead of repeating ., which will match anything, repeat anything but a space via \S+, so that only the URL part of the string will be matched:
const str = 'this is extra data which i do not need /type/123456/weqweqweqweqw/ these are more extra data which i dont need /';
console.log(str.match(/\/type\S+/));
It's tagged Python, so here is a solution:
import re
re.search(r"/type/[^/]*/[^/]*/",str)
Out: <_sre.SRE_Match object; span=(39, 66), match='/type/123456/weqweqweqweqw/'>

javascript regex insert new element into expression

I am passing a URL to a block of code in which I need to insert a new element into the regex. Pretty sure the regex is valid and the code seems right but no matter what I can't seem to execute the match for regex!
//** Incoming url's
//** url e.g. api/223344
//** api/11aa/page/2017
//** Need to match to the following
//** dir/api/12ab/page/1999
//** Hence the need to add dir at the front
var url = req.url;
//** pass in: /^\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var re = myregex.toString();
//** Insert dir into regex: /^dir\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var regVar = re.substr(0, 2) + 'dir' + re.substr(2);
var matchedData = url.match(regVar);
matchedData === null ? console.log('NO') : console.log('Yay');
I hope I am just missing the obvious but can anyone see why I can't match and always returns NO?
Thanks
Let's break down your regex
^\/api\/ this matches the beginning of a string, and it looks to match exactly the string "/api"
([a-zA-Z0-9-_~ %]+) this is a capturing group: this one specifically will capture anything inside those brackets, with the + indicating to capture 1 or more, so for example, this section will match abAB25-_ %
(?:\/page\/([a-zA-Z0-9-_~ %]+)) this groups multiple tokens together as well, but does not create a capturing group like above (the ?: makes it non-captuing). You are first matching a string exactly like "/page/" followed by a group exactly like mentioned in the paragraph above (that matches a-z, A-Z, 0-9, etc.
?$ is at the end, and the ? means capture 0 or more of the precending group, and the $ matches the end of the string
This regex will match this string, for example: /api/abAB25-_ %/page/abAB25-_ %
You may be able to take advantage of capturing groups, however, and use something like this instead to get similar results: ^\/api\/([a-zA-Z0-9-_~ %]+)\/page\/\1?$. Here, we are using \1 to reference that first capturing group and match exactly the same tokens it is matching. EDIT: actually, this probably won't work, since the text after /api/ and the text after /page/ will most likely be different, carrying on...
Afterwards, you are are adding "dir" to the beginning of your search, so you can now match someting like this: dir/api/abAB25-_ %/page/abAB25-_ %
You have also now converted the regex to a string, so like Crayon Violent pointed out in their comment, this will break your expected funtionality. You can fix this by using .source on your regex: var matchedData = url.match(regVar.source); https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source
Now you can properly match a string like this: dir/api/11aa/page/2017 see this example: https://repl.it/Mj8h
As mentioned by Crayon Violent in the comments, it seems you're passing a String rather than a regular expression in the .match() function. maybe try the following:
url.match(new RegExp(regVar, "i"));
to convert the string to a regular expression. The "i" is for ignore case; don't know that's what you want. Learn more here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Javascript Regex match everything after last occurrence of string

I am trying to match everything after (but not including!) the last occurrence of a string in JavaScript.
The search, for example, is:
[quote="user1"]this is the first quote[/quote]\n[quote="user2"]this is the 2nd quote and some url https://www.google.com/[/quote]\nThis is all the text I\'m wirting about myself.\n\nLook at me ma. Javascript.
Edit: I'm looking to match everything after the last quote block. So I was trying to match everything after the last occurrence of "quote]" ? Idk if this is the best solution but its what i've been trying.
I'll be honest, i suck at this Regex stuff.. here is what i've been trying with the results..
regex = /(quote\].+)(.*)/ig; // Returns null
regex = /.+((quote\]).+)$/ig // Returns null
regex = /( .* (quote\]) .*)$/ig // Returns null
I have made a JSfiddle for anyone to have a play with here:
https://jsfiddle.net/au4bpk0e/
One option would be to match everything up until the last [/quote], and then get anything following it. (example)
/.*\[\/quote\](.*)$/i
This works since .* is inherently greedy, and it will match every up until the last \[\/quote\].
Based on the string you provided, this would be the first capturing group match:
\nThis is all the text I\'m wirting about myself.\n\nLook at me ma. Javascript.
But since your string contains new lines, and . doesn't match newlines, you could use [\s\S] in place of . in order to match anything.
Updated Example
/[\s\S]*\[\/quote\]([\s\S]*)$/i
You could also avoid regex and use the .lastIndexOf() method along with .slice():
Updated Example
var match = '[\/quote]';
var textAfterLastQuote = str.slice(str.lastIndexOf(match) + match.length);
document.getElementById('res').innerHTML = "Results: " + textAfterLastQuote;
Alternatively, you could also use .split() and then get the last value in the array:
Updated Example
var textAfterLastQuote = str.split('[\/quote]').pop();
document.getElementById('res').innerHTML = "Results: " + textAfterLastQuote;

Categories

Resources