Well done Xbytor, you're quite right! I just tested it with the regexp tester on one of my help files (hence oridinary JS not the Adobe version) and it works as you describe (and as, before I did all my own testing, I would have expected).
I'm surprised to find a bug in regexp as it is so universal and I can see no reason for why Adobe would have needed to fiddle with it at all. But it is very useful to know that this is not normal regexp behaviour, perhaps we (you?) should report it as such at the Adobe forum so others know and Adobe can decide if it wants to take any notice or not.
Andrew
Photoshop Javascript - Regular Expressions
Photoshop Javascript - Regular Expressions
perhaps we (you?) should report it as such at the Adobe forum so others know and Adobe can decide if it wants to take any notice or not.
In adddition to the user to user forum, it might be helpful to post is here as well. This link is for reporting bugs and it might get more notice there.
http://www.adobe.com/misc/bugreport.html
Mike
In adddition to the user to user forum, it might be helpful to post is here as well. This link is for reporting bugs and it might get more notice there.
http://www.adobe.com/misc/bugreport.html
Mike
Photoshop Javascript - Regular Expressions
Something I discovered the other day. You can reference a bracketed expression later in the same regexp expression using \n.
For example the following captures the part of the string in quotes regardless of whether single or double quotes are used:
Code: Select allalert('he said "Goodbye" and went out'.match(/(['"])[^'"]*\1/g));
This can also be useful with xml:
Code: Select alltest();
function test () {
var string = "<exif:test>testvalue</exif:test>";
var re = /<(exif:.+)>(.*)<\/\1/;
var arr = re.exec(string);
alert(arr);
}
Andrew
For example the following captures the part of the string in quotes regardless of whether single or double quotes are used:
Code: Select allalert('he said "Goodbye" and went out'.match(/(['"])[^'"]*\1/g));
This can also be useful with xml:
Code: Select alltest();
function test () {
var string = "<exif:test>testvalue</exif:test>";
var re = /<(exif:.+)>(.*)<\/\1/;
var arr = re.exec(string);
alert(arr);
}
Andrew
Photoshop Javascript - Regular Expressions
Another RegExp bug.
Code: Select allfunction test () {
var str = 'test\ntest';
var str1 = str.replace(/\n/,'');// str1 = testtest
var str2 = str.replace(/\\n/,'');// str2 = test\ntest
}
test();
With normal Javascript it would be (and is, I just tested it) the other way round ie when you need to specify '\' as a character in it's own right it needs another '\' in front to make '\\'.
Andrew
Code: Select allfunction test () {
var str = 'test\ntest';
var str1 = str.replace(/\n/,'');// str1 = testtest
var str2 = str.replace(/\\n/,'');// str2 = test\ntest
}
test();
With normal Javascript it would be (and is, I just tested it) the other way round ie when you need to specify '\' as a character in it's own right it needs another '\' in front to make '\\'.
Andrew
Photoshop Javascript - Regular Expressions
I thought this was interesting enough to be worth reporting here. This is a real-world example from a script I am currently developing, so it is not set out in the easiest way possible as an example.
However, the crux of the matter is that in most cases you can build up a match RegExp either as a single RegExp 'match' method, or as a series of search RegExp's.
In my example which follows I compared the time required for each method and the search based approach proved to be around 3000 times faster to obtain exactly the same result.
Here is the string I am searching through:
bb/files/L1.dat
It countains (parts of) toSource renderings for four objects: ahsl0 - ahsl3;
Each object has four properties eg: ahsl0.elseif; ahsl0.condition; ahslo.ctext; ahsl0.pos.
What the overall function is doing is to capture those properties plus the object name (eg ahsl0) in a multi-D array.
Here's the code:
Code: Select allfunction processCommand (cStr) {
var re0,re1,re2,re3,s0,s1,s2,s3;
var sAr = []; var cmdAr = [];
cStr = cStr.replace(/\r|\n|\t/g,'');
// METHOD 1 USING SEARCH
re0 = /\.elseif=(.(?!;ahsl\d+\.condition=))+/;
re1 = /\.condition="(.(?!";ahsl\d+\.ctext=))+/;
re2 = /\.ctext="(.(?!";ahsl\d+\.pos=))+/;
re3 = /\.pos="(.(?!";))+/;
while((s0 = cStr.search(re0)) != -1) {
s1 = cStr.search(re1);
s2 = cStr.search(re2);
s3 = cStr.search(re3);
sAr.push([
cStr.substring(s0+8,re0.lastIndex+1),
cStr.substring(s1+12,re1.lastIndex+1),
cStr.substring(s2+8,re2.lastIndex+1),
cStr.substring(s3+6,re3.lastIndex+1)]);
}
// END OF METHOD 1
// METHOD 2 USING MATCH
var re4 = /(ahsl\d+)\.elseif=(.+);\1\.condition="(.+)";\1\.ctext=\"(.+)\";\1\.pos=\"([ \w]+)\";/g;
var nAr = [];
while ((matches = re4.exec(cStr)) != null) {
nAr.push([matches[2],matches[3],matches[4],matches[5]]);
}
// END OF METHOD 2
}
Using various Date variables at the start, after the first method and after the second method I compare the time taken. The average is 0 milliseconds for the first method and 3300 milliseconds for the second method. Reversing the order has no effect. You will see the specification of the match and search RegExps is pretty much equivalent.
While it can take more time to script multiple search RegExp's to achieve the same as a match RegExp it is likely to be well worth doing so.
Couple of details.
First, I take advantage of the working method for multiple passes of the same search RE variable that each pass starts AFTER the last character matched in the previous pass (see first while loop).
Second, to make the search based matching easier I use the lastIndex property of the search RegExp - when you search for a pattern the position returned will be the START of your pattern while the search RegExp lastIndex property will be the next position in the target string AFTER the match - so targetString.substring(searchpos,myRegExp.lastIndex) is the actual full match.
Andrew
However, the crux of the matter is that in most cases you can build up a match RegExp either as a single RegExp 'match' method, or as a series of search RegExp's.
In my example which follows I compared the time required for each method and the search based approach proved to be around 3000 times faster to obtain exactly the same result.
Here is the string I am searching through:
bb/files/L1.dat
It countains (parts of) toSource renderings for four objects: ahsl0 - ahsl3;
Each object has four properties eg: ahsl0.elseif; ahsl0.condition; ahslo.ctext; ahsl0.pos.
What the overall function is doing is to capture those properties plus the object name (eg ahsl0) in a multi-D array.
Here's the code:
Code: Select allfunction processCommand (cStr) {
var re0,re1,re2,re3,s0,s1,s2,s3;
var sAr = []; var cmdAr = [];
cStr = cStr.replace(/\r|\n|\t/g,'');
// METHOD 1 USING SEARCH
re0 = /\.elseif=(.(?!;ahsl\d+\.condition=))+/;
re1 = /\.condition="(.(?!";ahsl\d+\.ctext=))+/;
re2 = /\.ctext="(.(?!";ahsl\d+\.pos=))+/;
re3 = /\.pos="(.(?!";))+/;
while((s0 = cStr.search(re0)) != -1) {
s1 = cStr.search(re1);
s2 = cStr.search(re2);
s3 = cStr.search(re3);
sAr.push([
cStr.substring(s0+8,re0.lastIndex+1),
cStr.substring(s1+12,re1.lastIndex+1),
cStr.substring(s2+8,re2.lastIndex+1),
cStr.substring(s3+6,re3.lastIndex+1)]);
}
// END OF METHOD 1
// METHOD 2 USING MATCH
var re4 = /(ahsl\d+)\.elseif=(.+);\1\.condition="(.+)";\1\.ctext=\"(.+)\";\1\.pos=\"([ \w]+)\";/g;
var nAr = [];
while ((matches = re4.exec(cStr)) != null) {
nAr.push([matches[2],matches[3],matches[4],matches[5]]);
}
// END OF METHOD 2
}
Using various Date variables at the start, after the first method and after the second method I compare the time taken. The average is 0 milliseconds for the first method and 3300 milliseconds for the second method. Reversing the order has no effect. You will see the specification of the match and search RegExps is pretty much equivalent.
While it can take more time to script multiple search RegExp's to achieve the same as a match RegExp it is likely to be well worth doing so.
Couple of details.
First, I take advantage of the working method for multiple passes of the same search RE variable that each pass starts AFTER the last character matched in the previous pass (see first while loop).
Second, to make the search based matching easier I use the lastIndex property of the search RegExp - when you search for a pattern the position returned will be the START of your pattern while the search RegExp lastIndex property will be the next position in the target string AFTER the match - so targetString.substring(searchpos,myRegExp.lastIndex) is the actual full match.
Andrew
Photoshop Javascript - Regular Expressions
http://ps-scripts.com/bb/viewtopic.php?t=434 could be updated: in CS4 the behavior of | in regexp have been fixed (returns 1 as expected)