469,353 Members | 2,066 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,353 developers. It's quick & easy.

Regular Expression - Match all except last one

I know that the /g flag will match all occurrences. Is there a way, with
a Regular Expression, to match all occurrences *except* the last one?

pattern = /df/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString)

Gives me: asghasghasghasgh as it should.
What I want: asghasghasghasdf Where the last one is not replaced.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 19 '06 #1
17 10585
> "Randy Webb" <Hi************@aol.com> wrote:
news:Q7********************@comcast.com....

I know that the /g flag will match all occurrences. Is there a way,
with a Regular Expression, to match all occurrences *except* the
last one?

pattern = /df/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString)

Gives me: asghasghasghasgh as it should.
What I want: asghasghasghasdf Where the last one is not replaced.


Does the string always end with the pattern?

--
BootNic Sunday, March 19, 2006 1:19 AM

It's not that some people have willpower and some don't. It's that
some people are ready to change and others are not.
*James Gordon*

Mar 19 '06 #2
BootNic said the following on 3/19/2006 1:20 AM:
"Randy Webb" <Hi************@aol.com> wrote:
news:Q7********************@comcast.com....

I know that the /g flag will match all occurrences. Is there a way,
with a Regular Expression, to match all occurrences *except* the
last one?

pattern = /df/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString)

Gives me: asghasghasghasgh as it should.
What I want: asghasghasghasdf Where the last one is not replaced.


Does the string always end with the pattern?


Yes. And I think I know where you are headed but I will wait and see :)

The pattern I am actually matching is \r\n and the string is the .value
of a textarea. It is replacing it with ";\r\ndocument.write("
Where the " is part of the replacement. All it does is take code and
create document.write statements for them. What I end up with at the end
is an extra document.write(" that I don't want.

I could always just replace the last occurence of document.write(" but I
was hoping there was a simpler solution.
--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 19 '06 #3
> "Randy Webb" <Hi************@aol.com> wrote:
news:qZ********************@comcast.com....

BootNic said the following on 3/19/2006 1:20 AM:
"Randy Webb" <Hi************@aol.com> wrote:
news:Q7********************@comcast.com....

I know that the /g flag will match all occurrences. Is there a
way, with a Regular Expression, to match all occurrences *except*
the last one?

pattern = /df/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString)

Gives me: asghasghasghasgh as it should.
What I want: asghasghasghasdf Where the last one is not replaced.


Does the string always end with the pattern?


Yes. And I think I know where you are headed but I will wait and
see :)

The pattern I am actually matching is \r\n and the string is the
.value of a textarea. It is replacing it with ";\r\ndocument.write("
Where the " is part of the replacement. All it does is take code and
create document.write statements for them. What I end up with at
the end is an extra document.write(" that I don't want.

I could always just replace the last occurence of document.write("
but I was hoping there was a simpler solution.


Well now, I don't think I am comprehending the situation. It sounds like
you need to strip the the white space on each end of the sting before the
replace.

But I don't think that is the issue.

I was going to suggest one of two things.

pattern = /df(?=.)/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString);

Or

var myString = "asdfasdfasdfasdf";
while(myString.match(/df/g).length!=1){
myString=myString.replace(/df/,'gh')
}
alert(myString);

--
BootNic Sunday, March 19, 2006 2:21 AM

Get your facts first, and then you can distort them as much as you
please.
*Mark Twain *

Mar 19 '06 #4
Randy Webb wrote:
I know that the /g flag will match all occurrences. Is there a way, with
a Regular Expression, to match all occurrences *except* the last one?

pattern = /df/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString)

Gives me: asghasghasghasgh as it should.
What I want: asghasghasghasdf Where the last one is not replaced.


var newString = myString.replace(/df(.)/g,'gh$1');

--
Mar 19 '06 #5
Alexander Bartolich said the following on 3/19/2006 4:33 PM:
Randy Webb wrote:
I know that the /g flag will match all occurrences. Is there a way, with
a Regular Expression, to match all occurrences *except* the last one?

pattern = /df/g;
var myString = "asdfasdfasdfasdf";
var newString = myString.replace(pattern,'gh');
alert(newString)

Gives me: asghasghasghasgh as it should.
What I want: asghasghasghasdf Where the last one is not replaced.


var newString = myString.replace(/df(.)/g,'gh$1');


What do the (.) and $1 do? The code does exactly what I want it to do
but I want to understand it now.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 19 '06 #6
JRS: In article <qZ********************@comcast.com>, dated Sun, 19 Mar
2006 02:04:22 remote, seen in news:comp.lang.javascript, Randy Webb
<Hi************@aol.com> posted :
The pattern I am actually matching is \r\n and the string is the .value
of a textarea. It is replacing it with ";\r\ndocument.write("
Where the " is part of the replacement. All it does is take code and
create document.write statements for them. What I end up with at the end
is an extra document.write(" that I don't want.

I could always just replace the last occurence of document.write(" but I
was hoping there was a simpler solution.


Append the string '") ;' and you have effectively neutralised it.

Or can you pre-process myString with a .replace that removes just the
final \r\n? Or chop off the last 2 characters with substr or substring?
OTOH, can you not replace \r\n(.) with ";\r\ndocument.write("$1
which should not see a final \r\n ? Untested.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Mar 19 '06 #7
Dr John Stockton said the following on 3/19/2006 6:35 PM:
JRS: In article <qZ********************@comcast.com>, dated Sun, 19 Mar
2006 02:04:22 remote, seen in news:comp.lang.javascript, Randy Webb
<Hi************@aol.com> posted :
The pattern I am actually matching is \r\n and the string is the .value
of a textarea. It is replacing it with ";\r\ndocument.write("
Where the " is part of the replacement. All it does is take code and
create document.write statements for them. What I end up with at the end
is an extra document.write(" that I don't want.

I could always just replace the last occurence of document.write(" but I
was hoping there was a simpler solution.
Append the string '") ;' and you have effectively neutralised it.


That is, to date, the best suggestion I have seen/read :) I already
prepend document.write(' to it so appending isn't a big deal.
Or can you pre-process myString with a .replace that removes just the
final \r\n? Or chop off the last 2 characters with substr or substring?
That was also something I considered. Check to see if the last two are
\r\n (is that 2 or 4 characters?) and go from there. I need to do
different things if there is a final \r\n with no text following it.

Something else I considered was adding a final \r\n and then remove any
empty document.write statements (just so they aren't there, they won't
hurt anything).
OTOH, can you not replace \r\n(.) with ";\r\ndocument.write("$1
which should not see a final \r\n ? Untested.


It doesn't work correctly if there is a final \r\n in the string.

delim = /\r\n(.)/g;
output.value="document.write('"+input.value.replac e(delim,'\');\ndocument.write\(\'$1');

output and input are references to a textarea.
If the final line of the input is an empty line, where you type in text
and then press the Enter key with no more text, it breaks horribly. As
long as there is no \r\n at the very end of the string, it works perfectly.
--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

Mar 20 '06 #8
Randy Webb wrote:
Alexander Bartolich said the following on 3/19/2006 4:33 PM:
[...]
var newString = myString.replace(/df(.)/g,'gh$1');


What do the (.) and $1 do? The code does exactly what I want
it to do but I want to understand it now.


The dot matches any character.
The round brackets form a parenthesized subexpression.
The text matched by such subexpression is available in the
replacement text as $1, $2, $3, etc.

So what this does is to search for "df" followed by any character,
and replace that with "gh", followed by that character.

--
post tenebras lux. post fenestras tux.
Mar 20 '06 #9
Alexander Bartolich said the following on 3/20/2006 3:03 AM:
Randy Webb wrote:
Alexander Bartolich said the following on 3/19/2006 4:33 PM:
[...]
var newString = myString.replace(/df(.)/g,'gh$1');

What do the (.) and $1 do? The code does exactly what I want
it to do but I want to understand it now.


The dot matches any character.
The round brackets form a parenthesized subexpression.
The text matched by such subexpression is available in the
replacement text as $1, $2, $3, etc.

So what this does is to search for "df" followed by any character,
and replace that with "gh", followed by that character.


Thank you for the code and the explanation. I guess it's finally time
for me to read my references on Regular Expressions, asking questions,
and learn the things.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 20 '06 #10
Randy Webb said the following on 3/20/2006 6:58 AM:
Alexander Bartolich said the following on 3/20/2006 3:03 AM:
Randy Webb wrote:
Alexander Bartolich said the following on 3/19/2006 4:33 PM:
[...]
var newString = myString.replace(/df(.)/g,'gh$1');
What do the (.) and $1 do? The code does exactly what I want
it to do but I want to understand it now.


The dot matches any character.
The round brackets form a parenthesized subexpression.
The text matched by such subexpression is available in the
replacement text as $1, $2, $3, etc.

So what this does is to search for "df" followed by any character,
and replace that with "gh", followed by that character.


Thank you for the code and the explanation. I guess it's finally time
for me to read my references on Regular Expressions, asking questions,
and learn the things.


I think I spoke too soon for it doing exactly what I want it to do. I
think I gave a bad example with my first question as it doesn't actually
do what I need it to do in the real scenario.

This is my actual code:

var input = document.myForm.textarea1;
var output = document.myForm.textarea2;
delim = /\r\n(.)/g;
output.value = "document.write('" +
input.value.replace(delim,'\');\ndocument.write\(\ '$1');
output.value = output.value + "');";

What it does is take the input value of one textarea and create
document.write statements with every line. It is fine unless there is an
extra line at the end.

If the value of textarea1 is:

test<nothing more>

Then it works properly and give this in textarea2:

document.write('test');

But, if textarea1 looks like this:

test
<nothing more>

Where it has that extra carriage return then the code I get is this:

document.write('test
');

Which isn't what I want.

So, how do I deal with that extra line in the textarea?

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 20 '06 #11
> "Randy Webb" <Hi************@aol.com> wrote:
news:Le********************@comcast.com.... [snip] So, how do I deal with that extra line in the textarea?


Trim the white space.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript">
function tellerror(msg, url, lnn){
alert('Error message= '+msg+'\nURL= '+url+'\nLine Number= '+lnn)
return true
}
window.onerror=tellerror
</script>
<script type="text/javascript">
function cod(){
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'')};
var input = document.myForm.textarea1;
var output = document.myForm.textarea2;
delim = /(\r\n)+|(\n)+/g;
output.value='';
output.value="document.write('" +
input.value.trim().replace(delim,'\');\ndocument.w rite\(\'')+ "');"
}
</script>
<title></title>
</head>
<body>
<form action="javascript:cod()" name="myForm" id="myForm">
<textarea wrap="off" name="textarea1" cols="25" rows="15">
First line.


Second Line.
Third Line.
Last Line.

</textarea>
<textarea wrap="off" name="textarea2" cols="25" rows="15">
</textarea> <input type="submit" value="cod">
</form>
</body>
</html>
--
BootNic Monday, March 20, 2006 8:24 AM

Sometimes I think the surest sign that intelligent life exists
elsewhere in the universe is that none of it has tried to contact us.
*Bill Watterson*

Mar 20 '06 #12
Hi BootNic,

Great code enhancement. I'm an html/ javascript noobie, so I like
trolling the Q&As on this newsgroup to learn coding techniques.

Question: Do you concur in my belief that the preliminary null
assignment to output.value is superfluous because the succeeding
assignment completely replaces output.value's content?

Question: What's a good on-line source for learning the semantics of
your "String.prototype.trim" assignment statement? I don't mean the RE
stuff or replacing stings of leading or trailing space characters with
nulls. I mean:
- Does String have a property that has a trim method;
- Or is prototype a generic method to modify any method of any class

Thanks in advance,
Richard

Mar 20 '06 #13
Alexander Bartolich <al*****************@gmx.at> writes:
Alexander Bartolich said the following on 3/19/2006 4:33 PM:
[...]
var newString = myString.replace(/df(.)/g,'gh$1');
.... So what this does is to search for "df" followed by any character,
and replace that with "gh", followed by that character.


And it will fail on "dfdfdf", replacing only the first one.

If you expect the regexp engine to be recent, you can use positive
lookahead:
/df(?:.)/g
Then you could also just use negative lookahead on the end of text:
/df(?!$)/g

It's quite a lot harder without lookahead, since regular expressions
are notoriously hard to get to do a negative match (which is what
"not at the end" is).

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mar 20 '06 #14
> "Richard Lionheart" <RL******@USComputerGurus.com> wrote:
news:11**********************@g10g2000cwb.googlegr oups.com....

Hi BootNic,

Great code enhancement. I'm an html/ javascript noobie, so I like
trolling the Q&As on this newsgroup to learn coding techniques.

Question: Do you concur in my belief that the preliminary null
assignment to output.value is superfluous because the succeeding
assignment completely replaces output.value's content?

It should not be there, I would guess that I started to type out something
different then desided to paste instead.
Question: What's a good on-line source for learning the semantics of
your "String.prototype.trim" assignment statement? I don't mean
the RE stuff or replacing stings of leading or trailing space
characters with nulls. I mean:
- Does String have a property that has a trim method;
- Or is prototype a generic method to modify any method of any class

I would not normally use prototype, I used it this time simply because there
is something similar in the FAQ. It also should be outside of the function.

I prefer the Trim(str) function over the prototype. In example I posted,
a replace(/^\s+|\s$/g,'') in place of trim() would have done well.

http://jibbering.com/faq/#FAQ4_16

There is a lot of room for improvement on what I posted.

for example delim = /(\r\n)+|(\n)+/g; could be written different.

--
BootNic Monday, March 20, 2006 3:00 PM

"This is all very interesting, and I daresay you already see me
frothing at the mouth in a fit; but no, I am not; I am just winking
happy thoughts into a little tiddle cup."
*Nabokov, Lolita*

Mar 20 '06 #15
JRS: In article <Le********************@comcast.com>, dated Mon, 20 Mar
2006 07:05:16 remote, seen in news:comp.lang.javascript, Randy Webb
<Hi************@aol.com> posted :

So, how do I deal with that extra line in the textarea?


You could, maybe, .split the textarea at newlines; then scan the array
dealing with empty lines (e.g. put only non-empty ones into another
array, or remove trailing empties), also adding the ...(" and ");
strings to each element, then rejoin. It's not what you asked for, but
it might be clearer.

<URL:http://www.merlyn.demon.co.uk/js-quick.htm> Pack uses this

function Pak(F) { var S = F.Code.value, L = +F.Len.value, J, Re
S = S.replace(/(\r?\n){2,}/g, "\u2029") // PS
S = S.replace(/(\r?\n)/g, " ")
S = S.replace(/\s+/g, " ").split("\u2029")
if (L<1) L = F.Len.value = 1
Re = new RegExp("(.{1," + L + "}) ", "g")
J = S.length ; while (J--)
S[J] = (S[J].replace(/^\s+/, "")+" ").replace(Re, "$1\n")
F.Code.value = S.join("\n") }

to paragraph-pack textarea Code; but I didn't care about non-visible
characters in the output. You might get an idea from it. Or suggest an
improvement.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Mar 21 '06 #16
Dr John Stockton said the following on 3/20/2006 6:20 PM:
JRS: In article <Le********************@comcast.com>, dated Mon, 20 Mar
2006 07:05:16 remote, seen in news:comp.lang.javascript, Randy Webb
<Hi************@aol.com> posted :
So, how do I deal with that extra line in the textarea?
You could, maybe, .split the textarea at newlines; then scan the array
dealing with empty lines (e.g. put only non-empty ones into another
array, or remove trailing empties), also adding the ...(" and ");
strings to each element, then rejoin. It's not what you asked for, but
it might be clearer.


Ironically enough, that is exactly how I wrote it to start with and a
thread a few days ago about ABC:DEF: or something like that made me
start wondering if I could hack together a RegEx solution so I started
whacking. In the end, I went back to exactly what you suggested (that I
started out with).

Uncommented, this is the entire function:

function convertIt(){
var output = document.myForm.textarea2;
var myArray =
document.myForm.textarea1.value.replace('\'','\\\' ').split('\r\n');
for (var i=0;i<myArray.length;i++)
if (myArray[i] != '')
{
output.value += "document.write('" + myArray[i] + "');\r\n";
}
}

There are a few more things I am going to add to it, such as removing
double blank spaces, and empty lines with just a space in it. But
compared to the RegExp solutions so far, the above is - by far - simpler
and clearer (as you suggested).
<URL:http://www.merlyn.demon.co.uk/js-quick.htm> Pack uses this

function Pak(F) { var S = F.Code.value, L = +F.Len.value, J, Re
S = S.replace(/(\r?\n){2,}/g, "\u2029") // PS
S = S.replace(/(\r?\n)/g, " ")
S = S.replace(/\s+/g, " ").split("\u2029")
if (L<1) L = F.Len.value = 1
Re = new RegExp("(.{1," + L + "}) ", "g")
J = S.length ; while (J--)
S[J] = (S[J].replace(/^\s+/, "")+" ").replace(Re, "$1\n")
F.Code.value = S.join("\n") }

to paragraph-pack textarea Code; but I didn't care about non-visible
characters in the output. You might get an idea from it. Or suggest an
improvement.


I have saved it for future reference but admittedly, my knowledge of
RegExp's is not such that I could comment on it, mostly ask questions.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 21 '06 #17
JRS: In article <Ic********************@comcast.com>, dated Tue, 21 Mar
2006 01:15:47 remote, seen in news:comp.lang.javascript, Randy Webb
<Hi************@aol.com> posted :
<URL:http://www.merlyn.demon.co.uk/js-quick.htm> Pack uses this

function Pak(F) { var S = F.Code.value, L = +F.Len.value, J, Re S = S.replace(/(\r?\n){2,}/g, "\u2029") // PS PS is IIRC Paragraph-Space, represented by \u2029. Multiple blank lines
are turned into PS.
S = S.replace(/(\r?\n)/g, " ") Remaining newlines are turned into spaces.
S = S.replace(/\s+/g, " ").split("\u2029") Whitespace is turned into single-space, and each paragraph becomes an
array element.
if (L<1) L = F.Len.value = 1 The minimum line length is one character.
Re = new RegExp("(.{1," + L + "}) ", "g") Re matches any number of characters from 1 to L followed by a space, and
remembers the characters.
J = S.length ; while (J--) For each paragraph
S[J] = (S[J].replace(/^\s+/, "")+" ").replace(Re, "$1\n") remove leading spaces, add one trailing space[*]; replace, with a
newline, each occurrence of a space preceded with enough characters[+].
F.Code.value = S.join("\n") }
Join the paragraphs.

to paragraph-pack textarea Code; but I didn't care about non-visible
characters in the output. You might get an idea from it. Or suggest an
improvement.


I have saved it for future reference but admittedly, my knowledge of
RegExp's is not such that I could comment on it, mostly ask questions.

[*] H'mmm - in principle, maybe I should be removing initial trailing
spaces here. It appears unnecessary.
[+] That code is right; but I'm not entirely sure why.

The code of the page is now better; I've added, first,
S = S.replace(/^\s+|\s+$/g, "") // FAQ 4.15 Trim
to clean the ends.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
The Big-8 newsgroup management is attempting to reorganise its questionable
practices while retaining an elitist hegemony. Read <URL:news:news.groups>.
Mar 21 '06 #18

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Neri | last post: by
3 posts views Thread by LordHog | last post: by
3 posts views Thread by Zach | last post: by
5 posts views Thread by Cylix | last post: by
25 posts views Thread by Mike | last post: by
6 posts views Thread by Peter Duniho | last post: by
1 post views Thread by Mr.SpOOn | last post: by
reply views Thread by zhoujie | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.