Trying to get my head around some regex using JS .replace to replace an integer with a string.
For example, the string could be:
var string = 'image[testing][hello][0][welcome]';
I want to replace the '0' with another value. I was originally using this:
string.replace( /\[\d\]/g, '[newvalue]');
But when we start replacing double digits or more (12, 200, 3204, you get what I mean), it stops working properly. Not sure how to get it functioning the way I want it too.
Thanks in advance. Greatly appreciated.
You need to specify multiple digits:
string.replace( /\[\d+\]/g, '[newvalue]');
JS Fiddle demo
(Note the demo uses jQuery to iterate through the nodes, but it's merely a convenience, and has no bearing on the regular expression, it just demonstrates its function.)
The reason your original didn't work, I think, was because \d matches only a single digit, whereas the + operator/character specifies the preceding (in this case digit) character one or more times.
Reference:
JavaScript Regular Expressions, at the Mozilla Developer Network.
Use the following:
string.replace( /\[\d+\]/g, '[newvalue]');
That should match all digits in brackets.
Related
I'm formatting a datetime string in javascript by Regex, so I want:
Find and replace all d characters when d is not within other alphabetic characters. like this:
Find and replace all dd characters when dd is not within other alphabetic characters. like this:
I tested /\bd\b/mg pattern but its result is not which I want everytime.
How should I exclude unwanted cases in the following command:
str = str.replace(/\bd\b/mg, number);
The regular expression You posted does not consider _ as a word boundary, so it does not replace the character as expected.
In order to include this character as well, either before or after the d character to be replaced, You can use expressions similar to these:
To replace d:
/(\b|_)(d)(\b|_)/mg
To replace dd:
/(\b|_)(dd)(\b|_)/mg
Or to replace both in the same way (if it's acceptable):
/(\b|_)(d|dd)(\b|_)/mg
In comments under this answer in another thread on StackOverflow, it was also suggested to use a library that can format dates, instead of implementing it by Yourself.
UPDATE: As someone mentioned, the issue with this is also that including _ in the regular expression, removes it after the replacement. However, You can call replace and use capturing parentheses references, like this:
str.replace(/(\b|_)(d)(\b|_)/mg, "$1" + number + "$3")
I've updated earlier expressions posted in this answer to work with this method.
Please note that I'm not aware of all the cases You want to consider, so if You have any problems using the suggested solution or it does not work as expected in Your case, please let me know, so I can try to help.
I could use a lookahead and if you are not using JavaScript then a lookbehind as well.
example lookahead which checks if there is no following alpha character:
(?=[^a-zA-Z])
If you are using JavaScript it doesn't support lookbehind so you will need to use a capturing group and backreferencing.
For JS capture the part in the outermost parentheses and then use \1, \2... to target:
[^a-zA-Z](d(?=[^a-zA-Z]))
non-JS can use lookbehind:
(?<=[^a-zA-Z])d(?=[^a-zA-Z])
I'm creating a regex expression to get the variables passed to a JavaScript constructor.
The input is always going to follow along these lines:
app.use(express.static('public'));
And the regex I plan to use to strip out the unnecessary parts is:
(^app.use\()|(..$)
The first part of the regex gets everything up to the first parenthesis, and the it's supposed to pipe it to another expression which gets the last 2 characters of the string.
My issue is that it seems to be ignoring the second regex. I tried a few other expressions in the second part and they worked, but this one isn't.
What am I doing wrong?
Regex example on Regex101: https://regex101.com/r/jV9eH6/3
UPDATE:
This is not a duplicate of How to replace all occurrences of a string in JavaScript?
My question is about a specific issue with a regex, not about replacing one string with another in JavaScript.
You need to use multiline modifier. Whenever anchors ^, $ are used in your regex then feel free to add multi-line modifier m.
/(^app.use\()|(..$)/gm
DEMO
Let's say that I have a given string in javascript - e.g., var s = "{{1}}SomeText{{2}}SomeText"; It may be very long (e.g., 25,000+ chars).
NOTE: I'm using "SomeText" here as a placeholder to refer to any number of characters of plain text. In other words, "SomeText" could be any plain text string which doesn't include {{1}} or {{2}}. So the above example could be var s = "{{1}}Hi there. This is a string with one { curly bracket{{2}}Oh, very nice to meet you. I also have one } curly bracket!"; And that would be perfectly valid.
The rules for it are simple:
It does not need to have any instances of {{2}}. However, if it does, then after that instance we cannot encounter another {{2}} unless we find a {{1}} first.
Valid examples:
"{{2}}SomeText"
"{{1}}SomeText{{2}}SomeText"
"{{1}}SomeText{{1}}SomeText{{2}}SomeText"
"{{1}}SomeText{{1}}SomeText{{2}}SomeText{{1}}SomeText"
"{{1}}SomeText{{1}}SomeText{{2}}SomeText{{1}}SomeText{{1}}SomeText"
"{{1}}SomeText{{1}}SomeText{{2}}SomeText{{1}}SomeText{{1}}SomeText{{2}}SomeText"
etc...
Invalid examples:
"{{2}}SomeText{{2}}SomeText"
"{{1}}SomeText{{2}}SomeText{{2}}SomeText"
"{{1}}SomeText{{2}}SomeText{{2}}SomeText{{1}}SomeText"
etc...
This seems like a relatively easy problem to solve - and indeed I could easily solve it without regular expressions, but I'm keen to learn how to do something like this with regular expressions. Unfortunately, I'm not even sure if "conditionals and lookaheads" is a correct description of the issue in this case.
NOTE: If a workable solution is presented that doesn't involve "conditionals and lookaheads" then I will edit the title.
It's probably easier to invert the condition. Try to match any text that contains two consecutive instances of {{2}}, and if it doesn't match that, it's good.
Using this strategy, your pattern can be as simple as:
/{\{2}}([^{]*){\{2}}/
Demonstration
This will match a literal {{2}}, followed by zero or more characters other than {, followed by a literal {{2}}.
Notice that the second { needs to be escaped, otherwise, the regex engine will consider the {2} as to be a quantifier on the previous { (i.e. {{2} matches exactly two { characters).
Just in case you need to allow characters like {, and between the two {{2}}, you can use a pattern like this:
/{\{2}}((?!{\{1}}).)*{\{2}}/
Demonstration
This will match a literal {{2}}, followed by zero or more of any character, so long as those characters create a sequence like {{1}}, followed by a literal {{2}}.
(({{1}}SomeText)+({{2}}SomeText)?)*
Broken down:
({{1}}SomeText)+ - 1 to many {{1}} instances (greedy match)
({{2}}SomeText)? - followed by an optional {{2}} instance
Then the whole thing is wrapped in ()* such that the sequence can appear 0 to many times in a row.
No conditionals or lookaheads needed.
You said you can have one instance of {2} first, right?
^(.(?!{2}))(.{2})?(?!{2})((.(?!{2})){1}(.(?!{2}))({2})?)$
Note if {2} is one letter replace all dots with [^{2}]
The following expression:
targetString = targetString.replace(parenthesizedRegEx, "$3$1$11");
where parenthesizedRegEx is a valid parenthesized regular expression, replaces the matched text with a string that is the concatenation of the third item, the first item, the first item again, and the literal "1". It is as if it is ignoring the "two-digit" parentheses-item index "$11" and treating it as "$1" and the literal "1".
Is there some escaping or other separating that should be used?
This result occurs in FF and IE9.
Thanks for your help. I hope the answer is embarrassingly simple!!
Edit Update:
I did a jfiddle to demonstrate the issue comprehensively. The regexp I am using includes a negative lookahead assertion. It seems that when I include all the open parens for the assertion, it fails. If I include none of the insertion's open parens, it also fails. But if I include all but the assertion's initial opening paren, it works. I know that groups formed with (?:...) are not numbered. But is seems that one has to include all the other open parens within the assertion to get the count right. So you will see in the jfiddle that $11 does not work but that $10 does.
http://jsfiddle.net/pxMFx/1/
Thanks for looking at this.
This works fine for me:
var regex = /^(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w).*$/i;
alert("abcdefghijklmno".replace(regex,"$3$1$11"));
http://jsfiddle.net/J3RAa/
The key is that you need to match the whole string with your regular expression if you are targeting a specific location in it. Try taking the .* out of the above regex and you will see that it breaks the replacement.
I'm writing a javascript function which takes a regex and some elements against which it matches the regex against the name attribute.
Let's say i'm passed this regex
/cmw_step_attributes\]\[\d*\]/
and a string that is structured like this
"foo[bar][]chicken[123][cmw_step_attributes][456][name]"
where all the numbers could vary, or be missing. I want to match the regex against the string in order to swap out the 456 for another number (which will vary), eg 789. So, i want to end up with
"foo[bar][]chicken[123][cmw_step_attributes][789][name]"
The regex will match the string, but i can't swap out the whole regex for 789 as that will wipe out the "[cmw_step_attributes][" bit. There must be a clean and simple way to do this but i can't get my head round it. Any ideas?
thanks, max
Capture the first part and put it back into the string.
.replace(/(cmw_step_attributes\]\[)\d*/, '$1789');
// note I removed the closing ] from the end - quantifiers are greedy so all numbers are selected
// alternatively:
.replace(/cmw_step_attributes\]\[\d*\]/, 'cmw_step_attributes][789]')
Either literally rewrite part that must remain the same in replacement string, or place it inside capturing brackets and reference it in replace.
See answer on: Regular Expression to match outer brackets.
Regular expressions are the wrong tool for the job because you are dealing with nested structures, i.e. recursion.
Have you tried:
var str = 'foo[bar][]chicken[123][cmw_step_attributes][456][name]';
str.replace(/cmw_step_attributes\]\[\d*?\]/gi, 'cmw_step_attributes][XXX]');