How can I retrieve the word my from between the two rounded brackets in the following sentence using a regex in JavaScript?
"This is (my) simple text"
console.log(
"This is (my) simple text".match(/\(([^)]+)\)/)[1]
);
\( being opening brace, ( — start of subexpression, [^)]+ — anything but closing parenthesis one or more times (you may want to replace + with *), ) — end of subexpression, \) — closing brace. The match() returns an array ["(my)","my"] from which the second element is extracted.
var txt = "This is (my) simple text";
re = /\((.*)\)/;
console.log(txt.match(re)[1]);
jsFiddle example
You may also try a non-regex method (of course if there are multiple such brackets, it will eventually need looping, or regex)
init = txt.indexOf('(');
fin = txt.indexOf(')');
console.log(txt.substr(init+1,fin-init-1))
For anyone looking to return multiple texts in multiple brackets
var testString = "(Charles) de (Gaulle), (Paris) [CDG]"
var reBrackets = /\((.*?)\)/g;
var listOfText = [];
var found;
while(found = reBrackets.exec(testString)) {
listOfText.push(found[1]);
};
Use this to get text between closest ( and ):
const string = "This is (my) (simple (text)"
console.log( string.match(/\(([^()]*)\)/)[1] )
console.log( string.match(/\(([^()]*)\)/g).map(function($0) { return $0.substring(1,$0.length-1) }) )
Results: my and ["my","text"].
EXPLANATION
--------------------------------------------------------------------------------
\( '('
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
[^()]* any character except: '(', ')' (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
\) ')'
to get fields from string formula.
var txt = "{{abctext/lsi)}} = {{abctext/lsi}} + {{adddddd}} / {{ttttttt}}";
re = /\{{(.*?)\}}/g;
console.log(txt.match(re));
to return multiple items within rounded brackets
var res2=str.split(/(|)/);
var items=res2.filter((ele,i)=>{
if(i%2!==0) {
return ele;
}
});
Related
This question already exists:
Polymer reset parameters format not working
Closed 2 years ago.
I have a string that outputs like this:
"firstName" "lastName"
I need to the output to be like
"firtName lastName"
or else I get bad string request. I have tried different regex combinations that could achieve that however so far I can remove the quotes at the beginning and end of the string and the ones in the middle.
var string = '"firstName" ,"lastName"';
var stringWithoutCommas = string.replace(/,/g, '');
var stringWithoutExtQuotes = stringWithoutCommas.replace(/^"(.+(?="$))"$/, '$1');
console.log(stringWithoutExtQuotes); //firstName" "lastName
thanks you.
var string = '"firstName" ,"lastName"';
console.log(
string.replace(/"(\w*)\W*(\w*)"/, function(_, match1, match2){
return `"${match1} ${match2}"`;
})
);
You could grab the two strings and rebuild the string you want.
One approach
const input = '"firstName" "lastName"'
console.log('"'+input.replace(/"(.+?)"/g,'$1')+'"')
Extract all between double quotes and join the results:
const string = '"firstName" ,"lastName"';
console.log(Array.from(string.matchAll(/"([^"]+)"/g), x=>x[1]).join(" "));
Regex: "([^"]+)"
Explanation
--------------------------------------------------------------------------------
" '"'
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
[^"]+ any character except: '"' (1 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
" '"'
See proof.
This should be answer to your question.
function myFunction() {
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var result = fruits.join(",");
}
I'm trying to match all href within a string, but exclude (I believe using negative lookahead) when the href contains a specific text, such as login, for example:
const str = `This is some a string google and this is another that should not be found login`
const match = str.match(/href="(.*?)"/g)
console.log(match)
This matches all of the href, but doesn't factor in the exclusion of login being found in one. I've tried a few different variations, but really haven't gotten anywhere. Any help would be greatly appreciated!
You can use this regex which does a negative look behind just before the quote,
href="(.*?)(?<!login)"
Demo,
https://regex101.com/r/15DwZE/1
Edit 1:
As fourth bird pointed out that above regex may not work in general and instead of coming up with a complicated regex that can cover all possibilities of login appearance in url to be rejected, here is a javascript solution.
var myString = 'This is some a string google and this is another that should not be found login';
var myRegexp = /href="(.*?)"/g;
match = myRegexp.exec(myString);
while (match != null) {
if (match[1].indexOf('login') == -1) {
console.log(match[1]);
}
match = myRegexp.exec(myString);
}
You could do this without a regex using a DOMParser and use for example includes to check if href contains your string.
let parser = new DOMParser();
let html = `This is some a string google and this is another that should not be found login`;
let doc = parser.parseFromString(html, "text/html");
let anchors = doc.querySelectorAll("a");
anchors.forEach(a => {
if (!a.href.includes("login")) {
console.log(a.href);
}
});
You can have temporary HTML node and get all <a> tags from it. Then filter by href. Sample code:
const str = `This is some a string google and this is another that should not be found login`;
const d = document.createElement('div');
d.innerHTML = str;
Array.from(d.getElementsByTagName("a")).filter(a => !/login/.test(a.href))
You can use this regex to do that
/<[\w:]+(?=\s)(?=(?:[^>"']|"[^"]*"|'[^']*')*?\shref\s*=\s*(?:(['"])(?:(?!\1|login)[\S\s])*\1))\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]*?)+>/
https://regex101.com/r/LEQL7h/1
More info
< [\w:]+ # Any tag
(?= \s )
(?= # Asserttion (a pseudo atomic group)
(?: [^>"'] | " [^"]* " | ' [^']* ' )*?
\s href \s* = \s* # href attribute
(?:
( ['"] ) # (1), Quote
(?:
(?! \1 | login ) # href cnnot contain login
[\S\s]
)*
\1
)
)
# Have href that does not contain login, match the rest of tag
\s+
(?: " [\S\s]*? " | ' [\S\s]*? ' | [^>]*? )+
>
I'm creating regex in JavaScript that find all groups occurrences, all optional.
I have collected optional groups (thanks for #wiktor-stribiżew) now. Missing thing is gathering characters between new- prefix and first occurred group.
Input:
new-rooms-3-area-50
new-poland-warsaw-rooms-3-area-50-bar
new-some-important-location-rooms-3-asdads-anything-area-50-uiop
new-another-location-area-50-else
Requested output:
["rooms-3", "area-50"]
["poland-warsaw", "rooms-3", "area-50"]
["some-important-location", "rooms-3", "area-50"]
["another-location", "area-50"]
I have now
new-(?:.*?(rooms-\d+))?.*?(area-\d+)
regex. I think that collecting .* between new- and rooms|area may be stupid solution.
Online demo: https://regex101.com/r/QvmYN0/5
Note: I created two separated questions, because it refers to 2 separately problems. I hope that somebody have similar problems in the future.
I think it is better to split by steps like this:
// Split by \n to work with each line
getArrays = input => input.split`\n`.map(x => {
// Split by your desired delimiters:
// -dashes which has "area" or "rooms" in front
return x.split(/-(?=area-|rooms-)/g).map(y => {
// remove the "new-" from start or anything in front the numbers
return y.replace(/^new-|\D+$/, '');
// make sure you don't have empty cases
}).filter(y => y);
});
var txt = `new-rooms-3-area-50
new-poland-warsaw-rooms-3-area-50-bar
new-some-important-location-rooms-3-asdads-anything-area-50-uiop
new-another-location-area-50-else`;
console.log(getArrays(txt));
EDIT:
The above code returns the requested output. However, I was thinking you should want an array of models instead:
// initial state of your model
getModel = () => ({
new: '',
area: 0,
rooms: 0,
});
// the function that will return the array of models:
getModels = input => input.split`\n`.map(line => {
var model = getModel();
// set delimiters:
var delimiters = new RegExp(
'-(?=(?:' + Object.keys(model).join`|` + ')-)', 'g');
// set the properties of your model:
line.split(delimiters).forEach(item => {
// remove non-digits after the last digit:
item.replace(/(\d)\D+$/, '$1')
// set each matched property:
.replace(/^([^-]+)-(.*)/,
(whole_match, key, val) => model[key] = val);
});
return model;
});
var txt = `new-rooms-3-area-50
new-poland-warsaw-rooms-3-area-50-bar
new-some-important-location-rooms-3-asdads-anything-area-50-uiop
new-another-location-area-50-else`;
console.log(getModels(txt));
This is the high-end solution which does it all at once.
Doesn't split or massage the data, just takes it as is (and always will be).
It may not be for beginners, but be for the more experienced.
(Note that I don't know JS, but I can tell you, this took about 20 minutes
googling about strings. This is just too easy, do people really get paid
to do this ?!)
This uses exec to push each element ( group 2 )
and create an array of records, one for each line.
( ^ new ) # (1)
|
( # (2 start)
(?: rooms | area )
- \d+
| (?:
(?:
(?!
(?: rooms | area )
- \d+
)
[a-z]
)+
(?:
-
(?:
(?!
(?: rooms | area )
- \d+
)
[a-z]
)+
)+
)
) # (2 end)
var strTarget = "\
new-rooms-3-area-50\n\
new-poland-warsaw-rooms-3-area-50-bar\n\
new-some-important-location-rooms-3-asdads-anything-area-50-uiop\n\
new-another-location-area-50-else\n\
";
var RxLine = /^new.+/mg;
var RxRecord = /(^new)|((?:rooms|area)-\d+|(?:(?:(?!(?:rooms|area)-\d+)[a-z])+(?:-(?:(?!(?:rooms|area)-\d+)[a-z])+)+))/g;
var records = [];
var matches
var match;
while( (match = RxLine.exec( strTarget )) ){
var line = match[0];
matches = [];
while( (match = RxRecord.exec( line )) ){
if ( match[2] )
matches.push( match[2] );
}
records.push( matches );
}
console.log( records );
Here you go:
new-(.*?)?-?(rooms-\d+|area-\d+).*?(area-\d+)?.*
Demo: https://regex101.com/r/Qvdkdx/1
I have string:
=?windows-1256?B?IObH4cPM5dLJIA==?= =?windows-1256?B?x+HYyO3JIC4uLg==?= =?windows-1256?B?LiDH4djj5s3Hyg==?= =?windows-1256?B?Rlc6IOTP5skgKA==?=
I need to extract all matches between ?B? and ==?=.
As a result I need:
IObH4cPM5dLJIA
x+HYyO3JIC4uLg
LiDH4djj5s3Hyg
Rlc6IOTP5skgKA
P.S. This string is taken from textarea and after function executed, script should replace current textarea value with result. I've tried everything,
var result = str.substring(str.indexOf('?B?')+3,str.indexOf('==?='));
Works almost the way I need, but it only finds first match. And this doesn't work:
function Doit(){
var str = $('#test').text();
var pattern = /(?B?)([\s\S]*?)(==?=)/g;
var result = str.match(pattern);
for (var i = 0; i < result.length; i++) {
$('#test').html(result);
};
}
? has a special meaning in regex which matches preceding character 0 or 1 time..
So, ? should be escaped with \?
So the regex should be
(?:\?B\?)(.*?)(?:==\?=)
[\s\S] has no effect and is similar to .
The metacharacter ? needs escaping, i.e. \? so it is treated as a literal ?.
[\s\S] is important as it matches all characters including newlines.
var m,
pattern = /\?B\?([\s\S]*?)==\?=/g;
while ( m = pattern.exec( str ) ) {
console.log( m[1] );
}
// IObH4cPM5dLJIA
// x+HYyO3JIC4uLg
// LiDH4djj5s3Hyg
// Rlc6IOTP5skgKA
Or a longer but perhaps clearer way of writing the above loop:
m = pattern.exec( str );
while ( m != null ) {
console.log( m[1] );
m = pattern.exec( str );
}
The String match method does not return capture groups when the global flag is used, but only the full match itself.
Instead, the capture group matches of a global match can be collected from multiple calls to the RegExp exec method. Index 0 of a match is the full match, and the further indices correspond to each capture group match. See MDN exec.
Silly question, but I do not know how to find (2000) into a regular expression and replace it with [2000]
You can do:
str.replace(/\((\d+)\)/g, "[$1]");
Regex used: \((\d+)\)
( and ) are special char in regex
used for grouping, to match literal
( ), you need to escape them as
\( \)
\d is short for a digit. \d+
means one or more digits.
( ) is to group and remember the
number. The remembered number will
later be used in replacement.
g for global replacement. Mean
every occurrence of the patten in the
string will be replaced.
$1 is the number between (
)that was grouped and remembered.
/ / are the regex delimiters.
function _foo(str) {
return str.replace(/[(](\d*)[)]/, '[$1]');
}
alert( _foo("(2000)") ); // -> '[2000]'
alert( _foo("(30)") ); // -> '[30]'
alert( _foo("(abc)") ); // -> '(abc)'
alert( _foo("()") ); // -> '[]'
Like this: yourString.replace(/\(2000\)/, "[2000]");
Try this:
function foo(S) {
return S.replace(/\(([^\)]+)\)/g,"[$1]");
}