Replace each RegExp match with different text in ActionScript 3 - regex

I'd like to know how to replace each match with a different text?
Let's say the source text is:
var strSource:String = "find it and replace what you find.";
..and we have a regex such as:
var re:RegExp = /\bfind\b/g;
Now, I need to replace each match with different text (for example):
var replacement:String = "replacement_" + increment.toString();
So the output would be something like:
output = "replacement_1 it and replace what you replacement_2";
Any help is appreciated..

You could also use a replacement function, something like this:
var increment : int = -1; // start at -1 so the first replacement will be 0
strSource.replace( /(\b_)(.*?_ID\b)/gim , function() {
return arguments[1] + "replacement_" + (increment++).toString();
} );

I came up with a solution finally..
Here it is, if anyone needs:
var re:RegExp = /(\b_)(.*?_ID\b)/gim;
var increment:int = 0;
var output:Object = re.exec(strSource);
while (output != null)
{
var replacement:String = output[1] + "replacement_" + increment.toString();
strSource = strSource.substring(0, output.index) + replacement + strSource.substring(re.lastIndex, strSource.length);
output = re.exec(strSource);
increment++;
}
Thanks anyway...

leave off the g (global) flag and repeat the search with the appropriate replace string. Loop until the search fails

Not sure about actionscript, but in many other regex implementations you can usually pass a callback function that will execute logic for each match and replace.

Related

Jest cell name won't recognise regex [duplicate]

I want to add a (variable) tag to values with regex, the pattern works fine with PHP but I have troubles implementing it into JavaScript.
The pattern is (value is the variable):
/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is
I escaped the backslashes:
var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "" + value + ""));
But this seem not to be right, I logged the pattern and its exactly what it should be.
Any ideas?
To create the regex from a string, you have to use JavaScript's RegExp object.
If you also want to match/replace more than one time, then you must add the g (global match) flag. Here's an example:
var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;
var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.
JSFiddle demo here.
In the general case, escape the string before using as regex:
Not every string is a valid regex, though: there are some speciall characters, like ( or [. To work around this issue, simply escape the string before turning it into a regex. A utility function for that goes in the sample below:
function escapeRegExp(stringToGoIntoTheRegex) {
return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;
var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.
JSFiddle demo here.
Note: the regex in the question uses the s modifier, which didn't exist at the time of the question, but does exist -- a s (dotall) flag/modifier in JavaScript -- today.
If you are trying to use a variable value in the expression, you must use the RegExp "constructor".
var regex = "(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")
I found I had to double slash the \b to get it working. For example to remove "1x" words from a string using a variable, I needed to use:
str = "1x";
var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
inv=inv.replace(regex, "");
You don't need the " to define a regular expression so just:
var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax
If value is a variable and you want a dynamic regular expression then you can't use this notation; use the alternative notation.
String.replace also accepts strings as input, so you can do "fox".replace("fox", "bear");
Alternative:
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");
Keep in mind that if value contains regular expressions characters like (, [ and ? you will need to escape them.
I found this thread useful - so I thought I would add the answer to my own problem.
I wanted to edit a database configuration file (datastax cassandra) from a node application in javascript and for one of the settings in the file I needed to match on a string and then replace the line following it.
This was my solution.
dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'
// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
// need to use double escape '\\' when putting regex in strings !
var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
var myRegExp = new RegExp(searchString + re, "g");
var match = myRegExp.exec(data);
var replaceThis = match[1];
var writeString = data.replace(replaceThis, newString);
fs.writeFile(file, writeString, 'utf-8', function (err) {
if (err) throw err;
console.log(file + ' updated');
});
});
}
searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"
replaceStringNextLine(dse_cassandra_yaml, searchString, newString );
After running, it will change the existing data directory setting to the new one:
config file before:
data_file_directories:
- /var/lib/cassandra/data
config file after:
data_file_directories:
- /mnt/cassandra/data
Much easier way: use template literals.
var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false
Using string variable(s) content as part of a more complex composed regex expression (es6|ts)
This example will replace all urls using my-domain.com to my-other-domain (both are variables).
You can do dynamic regexs by combining string values and other regex expressions within a raw string template. Using String.raw will prevent javascript from escaping any character within your string values.
// Strings with some data
const domainStr = 'my-domain.com'
const newDomain = 'my-other-domain.com'
// Make sure your string is regex friendly
// This will replace dots for '\'.
const regexUrl = /\./gm;
const substr = `\\\.`;
const domain = domainStr.replace(regexUrl, substr);
// domain is a regex friendly string: 'my-domain\.com'
console.log('Regex expresion for domain', domain)
// HERE!!! You can 'assemble a complex regex using string pieces.
const re = new RegExp( String.raw `([\'|\"]https:\/\/)(${domain})(\S+[\'|\"])`, 'gm');
// now I'll use the regex expression groups to replace the domain
const domainSubst = `$1${newDomain}$3`;
// const page contains all the html text
const result = page.replace(re, domainSubst);
note: Don't forget to use regex101.com to create, test and export REGEX code.
var string = "Hi welcome to stack overflow"
var toSearch = "stack"
//case insensitive search
var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'
https://jsfiddle.net/9f0mb6Lz/
Hope this helps

Using regular expressions to add numbers using find and replace in Notepad++

I have a SPROC which is having the multiple instances of string Say '#TRML_CLOSE'.
I want to make them to be concatenated with a sequence of numbers.
Eg:
Search and find string '#TRML_CLOSE'
And
Replace the 1st Instance with '#TRML_CLOSE_1',
Replace the 2nd Instance with '#TRML_CLOSE_2',
Replace the 3nd Instance with '#TRML_CLOSE_3',
and so on.
How do I achieve this in Notepad++ using expressions.
I don't know the extent you can script Notepad++, but I do know you can throw together a quick JavaScript snippet to do what you want. http://jsfiddle.net/x4eSr/
Just go to the JS fiddle, and hit the button.
document.getElementById("btn").onclick = function() {
var elm = document.getElementById("txt");
var val = elm.value;
var cnt = 1;
val = val.replace(/#TRML_CLOSE(?!=[_])/g, function(m) {
return m + "_" + cnt++;
});
elm.value = val;
};
Using JavaScript's string.replace(regex, function(){}) which calls the function on each match and a globally incremented "cnt" variable.

Regular Expression in Actionscript 3

I need a AS3 regular expression that allows me to find/replace in strings like these:
var str1:String = "<value1 att="1"> some text</value1>";
var str2:String = "<value1 att="1" var="a"> some text and more</value1>";
var str3:String = "<value1 att="ok" var="b" def="12"> some text</value1>";
to this:
str1 = "<value1 att="1">*some text</value1>";
str2 = "<value1 att="1" var="a">**some text and more</value1>";
str3 = "<value1 att="ok" var="b" def="12">*****some text</value1>";
I want to be able to replace the spaces at the beginning (inside the > <) for other character. It shouldn't affect the number of character at the right of the spaces or the attributes in the value1 definition.
Assuming that there are no "* " sequences in the text blocks, this should work:
var s:String = "<value1 att='ok' var='b' def='12'> some text</value1>";
//find all spaces after a tag closing bracket and replace with a *
s = s.replace(/>\s/g, ">*");
//find all spaces after a * and replace it with a *
//keep doing this until no more can be found
while (s.match(/>\*+\s/g).length) {
s = s.replace(/\*\s/g, "**");
}
I can't think of a way to do it in one replace though.
I think the easiest way to accomplish what you need is to use a function in replace() expression.
var replaceMethod:Function = function (match:String, tagName:String, tagContent:String, spaces:String, targetText:String, index:int, whole:String) : String
{
trace("\t", "found", spaces.length,"spaces in tag '"+tagName+"'");
trace("\t", "matched string:", match);
// check tag name or whatever you may want
// do something with found spaces
var replacement:String = spaces.replace(" ", "*");
return "<"+tagName+" "+tagContent+">"+replacement+targetText;
}
var str1:String = '<value1 att="1"> some text</value1>';
var exp:RegExp = /<(\w+)([ >].*?)>(\s+)(some text)/gm;
trace("before:", str1);
str1 = str1.replace(exp, replaceMethod);
trace("after:", str1);
It's not performance-safe though; if you are using huge blocks of text and/or launching this routine very frequently, you may want to do something more comlicated, but optimized. One optimization technique is reducing the number of arguments of replaceMathod().
p.s. I think this can be done with one replace() expression and without using replaceMethod(). Look at positive lookaheads and noncapturing groups, may be you can figure it out. http://livedocs.adobe.com/flex/3/html/help.html?content=12_Using_Regular_Expressions_09.html

String parsing with RegExp in Actionscript

I have a string that is similar to a path, but I have tried some regex patterns that are supposed to parse paths and they don't quite work.
Here's the string
f|MyApparel/Templates/Events/
I need the "name parts" between the slashes.
I tried (\w+) but the array came back [0] = "f" and [1] = "f".
I tested the pattern on http://www.gskinner.com/RegExr/ and it seems to work correctly.
Here's the AS code:
var pattern : RegExp = /(\w+)/g;
var hierarchy : Array = pattern.exec(params.category_id);
params.name = hierarchy.pop() as String;
pattern.exec() works like in JavaScript. It resets the lastIndex property every time it finds a match for a global regex, and next time you run it it starts from there.
So it does not return an array of all matches, but only the very next match in the string. Hence you must run it in a loop until it returns null:
var myPattern:RegExp = /(\w+)/g;
var str:String = "f|MyApparel/Templates/Events/";
var result:Object = myPattern.exec(str);
while (result != null) {
trace( result.index, "\t", result);
result = myPattern.exec(str);
}
I don't know between which two slashes you want but try
var hierarchy : Array = params.category_id.split(/[\/|]/);
[\/|] means a slash or a vertical bar.

What's wrong with my ActionScript Regex?

I am trying pull a field out of a string and return it.
My function:
public function getSubtype(ut:String):String {
var pattern:RegExp = new RegExp("X=(\w+)","i");
var nut:String = ut.replace(pattern, "$1");
trace("nut is " + nut);
return nut;
}
I'm passing it the string:
http://foo.bar.com/cgi-bin/ds.pl?type=boom&X=country&Y=day&Z=5
the trace statements return the above string with out modification.
I've tried the pattern out on Ryan Swanson's Flex 3 Regular Expresion Explorer and it returns: X=country. My wished for result is "country".
Must be obvious, but I can't see it. Any help will be appreciated.
TB
changed my function to the following and it works:
public function getSubtype2(ut:String):String {
trace("searching " + ut);
var pattern:RegExp = new RegExp("X=([a-z]+)");
var r:Object = pattern.exec(ut);
trace("result is " + r[1]);
return r[1].toString();
Interestingly, though, using X=(\w+) does not match and causes an error. ????
}
The replace method is used for replacing. That is if you want to modify the given string. Replacing given portion with his own occurrence produces the same string.
I think you are looking for the match method, that produces an array of matches, see below.
function getSubtype(ut:String):String {
var pattern:RegExp = new RegExp("X=([a-z]+)","i");
var nut:Array = ut.match(pattern);
trace("nut is " + nut[1]);
return nut[1];
}
nut[0] beeing the full matched string, followed by nut[1] the first brackets group and so on.
The replace method does not mutate the string it operates on, it returns a new string. Try:-
var nut:String = ut.replace(pattern, "$1");
Note: I don't know ActionScript...
Your RE Explorer seems to return the matched pattern, see if there is a possibility to see the captures as well.
And if AS behaves like most languages I know, your replace() call replaces X=country with country.
Instead of
var pattern:RegExp = new RegExp("X=(\w+)","i");
You can write this:
var pattern:RegExp = /X=(\w+)/i;
Then you will not have problems with backslashes.
var pattern : RegExp = /[\\?&]X=([^&#]*)/g;
var XValue : String = pattern.exec(ut)[1];
See http://livedocs.adobe.com/flex/3/langref/RegExp.html#exec%28%29 for further explanations.
I have also found this flex regexp testing tool to be quite helpful.