Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Regular expression conditional replace 2

Status
Not open for further replies.

Danp129

Technical User
Nov 20, 2001
143
US
Hi guys, I'm having problems figuring out a replace statement or to be precise, how not to replace something under certain conditions.

This is the text I'm searching:

Code:
<input width="20" name="name1" value="hey">
<input width="20" name="name2">

This is my search expression:
Code:
<(?<start>([A-z0-9]+))(?<junk>[^>]+)(?<style>style=")(?<junk2>([^"]+))(?<end>")

This is the replace expression:
Code:
<${start}${junk}class="${start}001${end}

When it is ran, I get the following:
Code:
<input width="20" value="input001" value="hey">
<input width="20" value="input001">

I would like the regexp to not do a replace name= if the match already has a value= ... Any ideas?

Any help would be much appreciated, I don't have regexp down all that well yet.
 
bah, my search is actually
Code:
<(?<start>([A-z0-9]+))(?<junk>[^>]+)(?<name>name=")(?<junk2>([^"]+))(?<end>")

and replace is
Code:
<${start}${junk}value="${start}001${end}
 
It sounds like you need to use a "negative lookahead" match (?!pattern) for "value". I've never had a use for them before, but I know they exist. MSDN doesn't have them in the documentation for VBScript (but then again they don't have the (? notation either), but it apparently works for you. Try the JScript documentation for an explanation:


Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
Um - MSDN's had a bit of a reorg and design revamp, but that is the VBScript documentation for Regular Expressions (the JScript and VBScript documentation for Regular Expressions have always been the same)...
 
Thanks, I've been staring at it for awhile but still don't understand how to match name= ONLY if value= isn't in the string.
 
It looks like more of a tangle than a reorg. According to the title of the page, it's part of the JScript User's Guide. According to the "breadcrumbs" it's part of the VBScript User's Guide. There are TWO paths to get to that page, one thru the JSCript User's Guide and one thru the VBScript User's Guide, but it's the same page.

The page I referred to that doesn't even mention the (? syntax is the page for the Pattern property of the Regular Expression Object in the VBScript Language Reference here.

Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
I've never seen the (?<tag> syntax before, but guessed that it was naming matches, and after a short google search I found that you probably should be asking this question in the VB.NET forum, not the VB 5 & 6 forum. That syntax does not appear to be supported in VBScript. However, VBScript and JScript do have the lookahead syntax, so I tested your (modified) example in JScript and this works:
Code:
<(?<start>([A-z0-9]+))(?<junk>[^>]+)(?<name>name=")(?<junk2>([^"]+))(?<end>"[!](?!([^>]+)value)[/!])
A "negative lookahead match" searches for the string, but does not store it or more the matching "pointer". It will cause the regular expression to fail if it matches.

Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
>but it's the same page

Correct. And it always has been like that. It is just that before the reorg they didn't have the misleading JScript tag inserted (incorrectly) into the header strap.

>The page I referred to that doesn't even mention
The equivalent JScript pages are worse (here)

And for those that are interested in investigating this RegExp problem in VB6, here's the search pattern:

"<([A-z0-9]+)([^>]+)(name="")([^""]+)("")"

and here's the replacement string:

"<$1$2value=""$1001$5"

 
That's pretty much what I did (I just removed the ?<tag> parts entirely). I didn't bother with the replace expression since it already works. I just wanted to make the search pattern fail when it found the string "value", which the negative lookahead (also known as a "zero-width assertion") did. When used in a test expression it returns true when the string "value" is not present, and false when it is. Of course, it has to follow the "name" string to work properly. If I were doing this I'd check for the value string first, in a separate if statement.

Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
Thanks guys, I got this figured out at home after I found



Which helped me make:

(<\s*(\w+)\s+)(?!(?:name[^>]+value|value[^>]+name)+)([^>]*)(name=['"][^>]*?['"])([^>]*>)

I think the statment needs to be like that in case value comes before name instead of name assumed to be before value.

I decided not to do a replace directly from this regex. Instead I added the matches to a listview with checkboxes and checked which lines I wanted to replace.

This IS for VB6, I'm sorry I used incompatible commands, I was testing in "The Regulator". Gotta give you both a star for help, I had no idea to search for negative lookaheads which helped me find the above link, and I was also having problems replacing matches. I was trying \1 and ${1}.
 
Ironically, that's the same website I found when I did a search to verify my assumption that you were using named matches. I did a search for something like "regular expression named matches" and that one came up near the top. Looks like a good web site.

Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top