I've got a string
{'lalala'} text before \{'lalala'\} {'lalala'} text after
I want to get open bracket { but only if there is no escape char \ before.
Kind of /(?:[^\\])\{/ but it doesn't work at first statement.
The typical approach is to match the non-\ preceding character (or beginning of string), and then put it back in your replacement logic.
const input = String.raw`{'lalala'} text before \{'lalala'\} {'lalala'} text after`;
function replace(str) {
return input.replace(/(^|[^\\])\{'(\w+)'\}/g,
(_, chr, word) => chr + word.toUpperCase());
}
console.log(replace(input));
That's where ^ comes in: it anchors a piece of regex to the start of the string (or the line, in m multiline mode). Because a 'valid' opening bracket is either at the start of a string or after a non-\ character, we can use the following regex:
/(?:^|[^\\])\{/g
I added the g global flag because we want to match all 'valid' opening brackets. Example use:
console.log("{'lalala'} text before \\{'lalala'\\} {'lalala'} text after".match(/(?:^|[^\\])\{/g))
If you want to use the regex in a replace, you might want to capture the character before the bracket, as that gets replaced as well.
Related
I'm trying to come up with a regular expression to match words that are not the beginning of a function.
So it should match everything, that is not followed by an opening bracket.
The "something" following the text should also not be put into the [0]-element of the result. So for a string of test), the closing ) should not be part of the matching group, which is why something like ^([a-zA-Z][\w-]*)(\s|$|\|,)) doesn't work.
An additional problem is, that the function name may contain a dash (hence the [\w-]*).
My first attempt:
new RegExp(/^([a-zA-Z][\w-]*)(?!\()/)
This will match everything but the last character from the word, so tes from test(.
The next attempt was: new RegExp(/^([a-zA-Z][\w-]*)(?!\()\b/).
This will not match something like test( but will match get- from get-border(, because the - is a word breaking character.
I guess what I would need is "\b that is not a -", but not capturing it?
A few examples to maybe make clearer what I'm trying to accomplish:
foo( -> null
arg) -> arg
foo-bar( -> null
arg -> arg
The motivation for this problem: I want to split a text like foo(bar(argument)) into a list of tokens: ['foo(', 'bar(', 'argument', ')', ')'], given the regular expressions FUNCTION_START, ARGUMENT (< problem), FUNCTION_END.
Pseuo-Code:
while (line.length > 0) {
regExp.some(r => {
const match = line.match(r);
if (match) {
tokens.push(...);
line = line.replace(r, '').trim();
return true;
}
return false;
});
}
Which should not depend on the order of the regular expressions.
You may use expression:
^[a-zA-Z]+(?=\)|$)
^ Assert beginning of line.
[a-zA-Z]+ Alphabetic characters, lower and upper case, one or more.
(?=\)|$) Positive lookahead, match either a closing bracket ) or end of line $.
You can test the regex live here.
I'm trying to parse a string that always has the format: [firstpart:lastpart] in such a way that I can get "firstpart" and "lastpart" as separate items. The "firstpart" value is always a string, and the "lastpart" value could contain integers and text. The whole string [firstpart:lastpart] could be surrounded by any amount of other text that I don't need, hence the brackets.
I've been trying to modify this:
([^:\s]+):([^:\s]+)
As is, it gets me this:
[firstpart:lastpart
[firstpart
lastpart]
So it's just that I need to remove the open and close brackets from 2 and 3.
Is this possible with just a regex? I'm using JavaScript in a TinyMCE plugin, in case that is relevant.
Put \[ and \] at the beginning and end of the regular expression, respectively, and capture the text between them:
console.log(
'foo[firstpart:lastpart]bar'.match(/\[([^:]+):([^:\]]+)\]/)
);
You could match the opening and the closing bracket outside of the group:
\[([a-z]+):([a-z0-9]+)]
Note that [^:\s]+ Matches not a colon or a whitespace character which matches more than a string or a string or integers and escape the opening \[ to match it literally or else it would start a character class.
let str = "[firstpart:lastpart]";
console.log(str.match(/\[([a-z]+):([a-z0-9]+)]/i));
I want to remove all of the symbols (The symbol depends on what I select at the time) after each word, without knowing what the word could be. But leave them in before each word.
A couple of examples:
!!hello! my! !!name!!! is !!bob!! should return...
!!hello my !!name is !!bob ; for !
and
$remove$ the$ targetted$# $$symbol$$# only $after$ a $word$ should return...
$remove the targetted# $$symbol# only $after a $word ; for $
You need to use capture groups and replace:
"!!hello! my! !!name!!! is !!bob!!".replace(/([a-zA-Z]+)(!+)/g, '$1');
Which works for your test string. To work for any generic character or group of characters:
var stripTrailing = trail => {
let regex = new RegExp(`([a-zA-Z0-9]+)(${trail}+)`, 'g');
return str => str.replace(regex, '$1');
};
Note that this fails on any characters that have meaning in a regular expression: []{}+*^$. etc. Escaping those programmatically is left as an exercise for the reader.
UPDATE
Per your comment I thought an explanation might help you, so:
First, there's no way in this case to replace only part of a match, you have to replace the entire match. So we need to find a pattern that matches, split it into the part we want to keep and the part we don't, and replace the whole match with the part of it we want to keep. So let's break up my regex above into multiple lines to see what's going on:
First we want to match any number of sequential alphanumeric characters, that would be the 'word' to strip the trailing symbol from:
( // denotes capturing group for the 'word'
[ // [] means 'match any character listed inside brackets'
a-z // list of alpha character a-z
A-Z // same as above but capitalized
0-9 // list of digits 0 to 9
]+ // plus means one or more times
)
The capturing group means we want to have access to just that part of the match.
Then we have another group
(
! // I used ES6's string interpolation to insert the arg here
+ // match that exclamation (or whatever) one or more times
)
Then we add the g flag so the replace will happen for every match in the target string, without the flag it returns after the first match. JavaScript provides a convenient shorthand for accessing the capturing groups in the form of automatically interpolated symbols, the '$1' above means 'insert contents of the first capture group here in this string'.
So, in the above, if you replaced '$1' with '$1$2' you'd see the same string you started with, if you did 'foo$2' you'd see foo in place of every word trailed by one or more !, etc.
I have this RegExp, and i dont know what's wrong with it
tag = new RegExp('(\\['+tag+'=("|'|)(.*?)\1\\])((?:.|\\r?\\n)*?)\\[/'+tag+']','g');
The bbcode tags can have double quotation marks, single quotation marks or no quotation marks.
[tag="teste"]123[/tag]
[tag='teste']123[/tag]
[tag=teste]123[/tag]
Desired output in captures: teste and 123
To match the optional quotation marks, it should be ("|'|), (["|\']*) or ("|\'?)?
Whats wrong with the string
First, let's correct the syntax in your string
You need to define the var tag
tag = 'tag';
result = new RegExp( <...> );
You have unballanced quotes in '("|'|) <...> ', that needs to be escaped as ("|\'|)
Also, escape \1 as \\1
so now we have the expression '(\\['+tag+'=("|\'|)(.*?)\\1\\])((?:.|\\r?\\n)*?)\\[/'+tag+']' with the value:
(\[tag=("|'|)(.*?)\1\])((?:.|\r?\n)*?)\[/tag]
What's wrong with the RegEx
Only one thing really, in ("|\'|)(.*?)\\1 you're using \1 to match the same quotation mark as the one used as opening. However, the 1 refers to the first capturing group (the first parenthesis from left to right), but ("|'|) is actually the second set of parenthesis, the second group. All you need to do is change it to \2.
(\[tag=("|'|)(.*?)\2\])((?:.|\r?\n)*?)\[/tag]
That's it!
Let's add some final suggestions
Instead of .*? I would use [^\]]+ (any characters except "]")
Use the i modifier (case-insensitive match, for "[tag]...[/TaG]")
("|'|) is the same as ("|'?)
Instead of (?:.|\r?\n)*? I would use [\s\S]*? as #nhahtdh suggested
Code:
tag = 'tag';
result = new RegExp('(\\['+tag+'=("|\'?)([^\\]]+)\\2\\])([\\s\\S]*?)\\[/'+tag+']','gi');
Alternative: [EDIT: from info added in comments]
result = new RegExp('\\['+tag+'(?:=("|\'?)([^\\]]+)\\1)?\\]([\\s\\S]*?)\\[/'+tag+']', 'gi');
As for your second question: Although both (["|\']*) and ("|\'?) will match, the latter is the correct way for what you're trying to match. The * looks for 0 to infinite repetitions, and the | is interpreted as literal in a character class. Instead, ("|\'?) matches a single quote, a double quote, or none.
i want to replace last input character from keyboard to ''
My String Input are
sample string
"<p><strong>abscd sample text</strong></p>"
"<p>abscd sample text!</p>"
My last character is dynamic that can be any thing between
a to z, A to Z, 0 to 9, any special characters([~ / < > & ( . ] ).
So i need to replace just that character
for example in Sample 1 i need to replace "t" and in sample 2 in need to replace "!"
I tried below code. but it id not worked for me
var replace = '/'+somechar+'$/';
Any way to do it?
Step one
to replace the a character in a string, use replace() function of javaScript. Here is the MDN specification:
Returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match.
Step two
you need to location the character to be replaced through regular expression. You want to replace the last character of a string and this could be expressed as /(.+)(.)$/. . stands for any character, + means more than one character. Here (.+) matches all the character before the last one. (.) matches the last character.
What you want to replace is the one inside the second brackets. Thus you use the same string matched in the first bracket with $1 and replace whatever after it.
Here is the code to realize your intention:
text = 'abscd sample text';
text.replace(/(.+)(.)$/, '$1!');
Do you really need to use regular expressions? How about str = str.slice(0, -1); ? This will remove the last character.
If you need to replace a specific character, do it like this:
var replace = new RegExp(somechar + '$');
str = str.replace(replace, '');
You cannot use slashes in a string to construct a RegEx. This is different from PHP, for example.
I dont really understand which character you want to replace to what, but i think, you should use replace() function in JS: http://w3schools.com/jsref/jsref_replace.asp
string.replace(regexp/substr,newstring)
This means all keyboard character:
[\t\n ./<>?;:"'`!##$%^&*()[]{}_+=-|\\]
And this way you can replace all keyboard character before < mark to ""
string.replace("[a-zA-Z0-9\t\n ./<>?;:"'`!##$%^&*()[]{}_+=-|\\]<","<")