Double bracket pattern search in string - javascript

I have a regular expression to search in a string.
new RegExp("\\b"+searchText+"\\b", "i")
My strings:
"You are likely to find [[children]] in [[a school]]"
"[[school]] is for [[learning]]"
How can I search only the words in double brackets?
A regular expression should contain searchText as a function argument.

This RegEx will give you the basics of what you want:
\[\[[^\]]*\]\]
\[\[ matches the two starting brackets. A bracket is a special character in RegEx, hence it must be escaped with \
[^\]]* is a negated set that matches zero or more of any character except a closing bracket. This matches the content in-between the brackets.
\]\] matches the two closing brackets.
Here's a very basic example of what you could do with this:
let string = "You are likely to find [[children]] in [[a school]]<br>[[school]] is for [[learning]]";
string = string.replace(/\[\[[^\]]*\]\]/g, x => `<mark>${x}</mark>`);
document.body.innerHTML = string;

You can use this regex:
var str = `-- You are likely to find [[children]] in [[a school]]
-- [[school]] is for [[learning]]`;
var regex = /(?<=(\[\[))([\w\s]*)(?=(\]\]))/gm;
var match = str.match(regex);
console.log(match);

const re = /(?<=\[\[)[^\]]+(?=]])/gm
const string = `-- You are likely to find [[children]] in [[a school]]
-- [[school]] is for [[learning]]`
console.log(string.match(re))
const replacement = {
children: 'adults',
'a school': 'a home',
school: 'home',
learning: 'rest',
}
console.log(string.split(/(?<=\[\[)[^\]]+(?=]])/).map((part, index) => part + (replacement[string.match(re)[index]] || '')).join(''))

Related

Extract a part of a regex name

Examples of filenames
FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
FDIP_fr-fr-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
FDIP_de-de-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
REGEX is FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
The only part I need is the translation code which is 'en-gb', 'fr-fr' , 'de-de.
How do I extract just that part of the filename?
Modified the regex little bit to match the numbers and text. You can play around here
Explanation
to capture a group you need to wrap the regex into () this will capture as a group.
to do the named capturing you can (?<name_of_group>) and then you can access by name.
Here goes the matching process.
[a-z]{2} match 2 char from a-z
[a-zA-Z0-9] match any char of a-z or A-Z or 0-9
g means global flag i.e. match all.
i means ignore case.
var r = /FDIP_([a-z]{2}-[A-Z]{2})-[a-z]{2}_Text_v1_[0-9A-Z]{8}_[A-Z0-9]{14}.txt/gi;
let t = 'FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt';
let dd = r.exec(t);
console.log(dd[1]);
This is example of group capturing
See the name in the regex and the object destructing name is matching.
const { groups: { language } } = /FDIP_(?<language>[a-z]{2}-[A-Z]{2})-[a-z]{2}_Text_v1_[0-9A-Z]{8}_[A-Z0-9]{14}.txt/gi.exec('FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt');
console.log(language);
To solve your problem, you should:
Fix your regex:
FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
// to
FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[0-9]{8}_[0-9]{14}.txt
Use get value from first group by using regex.exec function
const fileNames = [
'FDIP_en-gb-nn_Text_v1_20190101_12345678901234.txt',
'FDIP_fr-fr-nn_Text_v1_20200202_12345678901234.txt',
'FDIP_de-de-nn_Text_v1_20180808_12345678901234.txt']
const cultureNames = fileNames.map(name => {
const matched = /FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[0-9]{8}_[0-9]{14}.txt/.exec(name)
return matched && matched[1]
})
console.log(cultureNames)
Change FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
to
let pattern = /FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[\w]{8}_[\w]{14}.txt/;
var str = 'FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt';
console.log(str.match(pattern)[1]);

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-()]+)?');

Allow only certain character in string. Javascript

I have no idea, why this simple code is not working. I am planning to match a string against the allowed pattern.
The string should ONLY have a-z, A-Z, 0-9, _ (underscore), . (dot) , - (hiphen).
Below is code:
var profileIDPattern = /[a-zA-Z0-9_.-]./;
var str = 'Heman%t';
console.log('hemant',profileIDPattern.test(str));
The code logs 'true' for below string, although these string DOES NOT match the pattern.
'Heman%t' -> true
'#Hemant$' -> true
I dont know what is the problem.
Try changing it to this RegExp (/^[a-zA-Z0-9_.-]*$/):
var profileIDPattern = /^[a-zA-Z0-9_.-]*$/;
var str1 = 'Hemant-._67%'
var str2 = 'Hemant-._67';
console.log('hemant1',profileIDPattern.test(str1));
console.log('hemant2',profileIDPattern.test(str2));
Issues : [a-zA-Z0-9_.-] will match any character inside [] and . will match anything after so basically it will match the mention character and any other character
Use ^ and $ anchor to mention start and end of match and remove .
^[a-zA-Z0-9_.-]+ : starting with any given value inside []
[a-zA-Z0-9_.-]+$ : one or more matches and $ to end the match
var profileIDPattern = /^[a-zA-Z0-9_.-]+$/;
console.log('hemant', profileIDPattern.test('Heman%t')); // no match -
console.log('hemant-._', profileIDPattern.test('hemant-._')); // valid match
console.log('empty', profileIDPattern.test('')); // no match ,empty

Regexp, capture between parentheses, javascript

I have regexp that extracts values between parentheses.
It's working most of the time but not when it ends with a parentheses
var val = 'STR("ABC(t)")';
var regExp = /\(([^)]+)\)/;.
var matches = regExp.exec(val);
​
console.log(matches[1]); //"ABC(t"
What I want is "ABC(t)".
Any ideas how I can modify my regexp to Achive this?
Update
The value is always inside the parentheses.
Some examples:
'ASD("123")'; => '123'
'ASD(123)'; => '123'
'ASD(aa(10)asda(459))'; => 'aa(10)asda(459)'
So first there is some text (always text). Then there is a (, and it always ends with a ). I want the value between.
You may use greedy dot matching inside Group 1 pattern: /\((.+)\)/. It will match the first (, then any 1+ chars other than linebreak symbols and then the last ) in the line.
var vals = ['STR("ABC(t)")', 'ASD("123")', 'ASD(123)', 'ASD(aa(10)asda(459))'];
var regExp = /\((.+)\)/;
for (var val of vals) {
var matches = regExp.exec(val);
console.log(val, "=>", matches[1]);
}
Answering the comment: If the texts to extract must be inside nested balanced parentheses, either a small parsing code, or XRegExp#matchRecursive can help. Since there are lots of parsing codes around on SO, I will provide XRegExp example:
var str = 'some text (num(10a ) ss) STR("ABC(t)")';
var res = XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/2.0.0/xregexp-all-min.js"></script>

Regex to grab strings between square brackets

I have the following string: pass[1][2011-08-21][total_passes]
How would I extract the items between the square brackets into an array? I tried
match(/\[(.*?)\]/);
var s = 'pass[1][2011-08-21][total_passes]';
var result = s.match(/\[(.*?)\]/);
console.log(result);
but this only returns [1].
Not sure how to do this.. Thanks in advance.
You are almost there, you just need a global match (note the /g flag):
match(/\[(.*?)\]/g);
Example: http://jsfiddle.net/kobi/Rbdj4/
If you want something that only captures the group (from MDN):
var s = "pass[1][2011-08-21][total_passes]";
var matches = [];
var pattern = /\[(.*?)\]/g;
var match;
while ((match = pattern.exec(s)) != null)
{
matches.push(match[1]);
}
Example: http://jsfiddle.net/kobi/6a7XN/
Another option (which I usually prefer), is abusing the replace callback:
var matches = [];
s.replace(/\[(.*?)\]/g, function(g0,g1){matches.push(g1);})
Example: http://jsfiddle.net/kobi/6CEzP/
var s = 'pass[1][2011-08-21][total_passes]';
r = s.match(/\[([^\]]*)\]/g);
r ; //# => [ '[1]', '[2011-08-21]', '[total_passes]' ]
example proving the edge case of unbalanced [];
var s = 'pass[1]]][2011-08-21][total_passes]';
r = s.match(/\[([^\]]*)\]/g);
r; //# => [ '[1]', '[2011-08-21]', '[total_passes]' ]
add the global flag to your regex , and iterate the array returned .
match(/\[(.*?)\]/g)
I'm not sure if you can get this directly into an array. But the following code should work to find all occurences and then process them:
var string = "pass[1][2011-08-21][total_passes]";
var regex = /\[([^\]]*)\]/g;
while (match = regex.exec(string)) {
alert(match[1]);
}
Please note: i really think you need the character class [^\]] here. Otherwise in my test the expression would match the hole string because ] is also matches by .*.
'pass[1][2011-08-21][total_passes]'.match(/\[.+?\]/g); // ["[1]","[2011-08-21]","[total_passes]"]
Explanation
\[ # match the opening [
Note: \ before [ tells that do NOT consider as a grouping symbol.
.+? # Accept one or more character but NOT greedy
\] # match the closing ] and again do NOT consider as a grouping symbol
/g # do NOT stop after the first match. Do it for the whole input string.
You can play with other combinations of the regular expression
https://regex101.com/r/IYDkNi/1
[C#]
string str1 = " pass[1][2011-08-21][total_passes]";
string matching = #"\[(.*?)\]";
Regex reg = new Regex(matching);
MatchCollection matches = reg.Matches(str1);
you can use foreach for matched strings.

Categories