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!

Search project for lines with two expressions on them, and replace second expression only

Status
Not open for further replies.

GriffMG

Programmer
Mar 4, 2002
6,305
FR
I think I'm being a bit dim this morning, but I can't seem to work this out for myself.

I have a largeish project and want to replace some text globally, rather than manually.

I want to change lines that run like this:
Code:
<input Type="Button" Name="cmdAcceptRequest" ID="cmdAcceptRequest" Value="Accept Document Request" Class="input-small" onclick="cmdAcceptRequest_onclick(frmAcceptRequest)">

for this:
Code:
<input Type="Button" Name="cmdAcceptRequest" ID="cmdAcceptRequest" Value="Accept Document Request" Class="btnclass" onclick="cmdAcceptRequest_onclick(frmAcceptRequest)">

So there are two conditions to be met to select the line - and I can use a regular expression to find them: 'Type="button".*input-small' but I only want to replace the 'input-small' with 'btnclass'

I know this is a VFP forum, and most of you will spot that the code is HTML, but I manage my web projects using the VFP9 IDE, because I think it rocks.
I could write a quick and dirty app which would do the above, but I'm sure it can be done in the IDE, using code references - but this morning it's beyond me.

Any help gratefully received.


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Code references can execute regular expressions to find matches. But the replacement isn't possible for just a specific part of the match. So you need to program a little or do this by hand finding the matches with your regex [tt]type="button".+input-small[/tt]

Bye, Olaf.

Olaf Doschke Software Engineering
 
Thank you Olaf



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
I have often faced this sort of problem over the years. My solution has been to write a simple generic program that accepts any batch of files, performs some transformation on them, and saves the results to a new set of files.

The program handles the work of locating and opening the files to be processed, and writing the output files. It calls a function called Process, which initially does nothing. For each application of the program, I write new code in the Process function that performs the specific transformation that is required. Usually, that code consists of just a few STRTRAN() or similar calls.

Griff, that might sound like a lot of work to solve your immediate problem, but the chances are that you would use such a program many times over a period. I certainly have - especially when working with HTML.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
GoFish is much faster and more flexible than Code Reference. It can even do the replacements for you, and you can preview the changes before you confirm them.
 
Even using groups (partial search string enclosed in brackets like [highlight #FCE94F](type="button").+(input-small)[/highlight] you don't get two selections/marks in the source code for a found match. Code References also executes such regex, but doesn't give you more detailed/partial/group results, but you might make use of groups in code with regex in other languages. I'd perhaps even go for .NET in that case, a simple console application and you have more tools around regex, if you like to use them, than if you use VFP with VB OLE regex class.

In VFP code you could make 'type="button"' the start delimiter and '>' the end delimiter of a STREXTRACT search and if the match you get contains 'class="input-small"' (all matches done case insensitive) you can replace that within the match with 'Class="btnclass"' and then replace the overall original match with that modified match in the whole HTML string.

It's crucial you don't look for 'class="input-small"' as end delimiter of STREXTRACT, as that might span multiple tags, one input tag with the correct type and a later tag with class="input-small" but another type. As you only want to find 'class="input-small"' within the tag that is 'type="button"' that's a problem of the regex, too, anyway.

It might be easiest to do in jQuery when the HTML is loaded as DOM and then querying such tags is easy, the overall changed HTML can be found in document.outerHTML, but that gives you HTML code, which overall is slightly modified by how the browser interprets and renders the original HTML and/or manipulations done on it by a jQuery ready function, so there are good reasons to process the html or script files themselves.

Bye, Olaf.

Olaf Doschke Software Engineering
 
I have downloaded GoFish, but to be frank I am thinking I can write something that does this in just a few minutes so that's what I am going to do.

I could have sworn the code references had a second search level - so you could search the sub set of selected references to do a find and replace on that.

Thank you all for your thoughts.



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Code References has the replace toolbar button in the results list, yes, that is a sublevel, but not a second search level, it's just asking for the "replace with" string.

It only has a simple replace of the whole result, not a search&replace within the results. The result list is even processed in terms of the positions originally found and in an early form had and poerhaps still has the error to take these positions, even if a first replace within the same method or prg already shifts match positions.

Using GoFish source code is surely the better solution than trying to fiddle with Code References code, although that also is available in xsoruce.zip of VFP. IIRC GoFish is based on the idea of an older legacy version of GoFish, which existed before Code References, but also has used code from Code References.

Bye, Olaf.

Olaf Doschke Software Engineering
 
In case anyone is interested in my very quick and dirty replacer...
I know it could be quite a bit faster, but this method definitely works and got the job done.
Code:
CLEAR
SET SAFETY OFF
SET MEMOWIDTH TO 8192
m.CRLF= CHR(13)+CHR(10)
m.Replacements = 0
m.ChangedFiles = 0
m.COUNT = ADIR(MYARRAY,"d:\[URL unfurl="true"]www\myWebApp\*.asp")[/URL]
FOR I = 1 TO m.COUNT
	? MYARRAY(I,1)
	m.BLCHANGED = .F.
	m.FILESTRING = FILETOSTR("d:\[URL unfurl="true"]www\myWebApp\"+MYARRAY(I,1))[/URL]
	m.OUTSTRING = ""
	m.TotalLines = MEMLINES(m.FILESTRING)
	FOR X=1 TO m.TotalLines
		m.STRING = MLINE(m.FILESTRING,X)
		IF 'TYPE="BUTTON"'$UPPER(m.STRING) .AND. "INPUT-SMALL"$UPPER(m.STRING)
			?? "."
			m.Replacements = m.Replacements +1
			m.STRING = STRTRAN(m.STRING,"input-small","button")
			m.BLCHANGED = .T.
		ENDIF
		m.OUTSTRING = m.OUTSTRING + m.CRLF + m.STRING
	NEXT
	IF BLCHANGED
		m.ChangedFiles = m.ChangedFiles+1
		STRTOFILE(m.OUTSTRING,"d:\[URL unfurl="true"]www\myWebApp\"+MYARRAY(I,1),0)[/URL]
	ENDIF
NEXT
? m.Count
? m.Replacements
? m.ChangedFiles

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Check RegexTool ( ) on github ; it allows you to not only test visually regular expressions in Vfp, it supports what Olaf mentions ( sub group match replace ) see attached image.

download the tool, and test using this regexp:

Code:
 (<input type="button").*?(Class="(input-small)")

Paste your text and use the 'replace group#' there put "3" and "btnClass" as shown.

Right now it works only in interactive mode, but you can automate the form since the source code is included.

( I'll try to release a wrapper for that soon )

vfpregex_tool_bpkvp1.jpg




Marco Plaza
@nfoxProject
 
Griff, you beat me to it. I was in the process of writing some code for you, but you got there first. I'll post my code anyway, for what it's worth:

Code:
lcDelim1 = [Accept Document Request" ]
lcDelim2 = [ onclick="cmdAcceptRequest]
lcReplace = [Class="btnclass"])
* For each line in the input:
lcExtr = STREXTRACT(lcInput, lcDelim1, lcDelim2)
lcOutput = STRTRAN(lcInput, lcExtr, lcReplace)

Obviously, this is just the core of the replacement routine. You already have all the surrounding code.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The way you have it you now depend on HTML having multiple lines, I know MEMLINES will also cut this into lines by the MEMOWIDTH even if the HTML is all on one line, but you still risc having multiple tags in one line and finding occurrences, which don't belong to the same tag. You know better than us, if your HTML is structured that way and even generated HTML often has linebreaks for sake of easier handling with browser developer tools and console in tests, so this is very pedantic.

But Marco points out a nice VFPX tool for this. Otherwise, editors like vi or emacs come to mind in allowing such search&replace actions.

Bye, Olaf.

Olaf Doschke Software Engineering
 
There are over 200,000 lines of code to search, so I needed a tool that wouldn't require visual checks.

I wrote all the code, so I know there are only a few 'split' lines, and the odd variation on a theme "button", "submit", 'Button' etc.
It is one of the advantages of writing code with a 'style' it's not hard to identify the exceptions.

Some lines are quite long - SQL selects mostly - and that's why I set the memo width to 8192, there is nothing that long.

Thanks Mike for the thought, I was sure there was a tool to do it - probably GoFish - but I didn't have time to learn it!


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Like Olaf, I also considered using a programmable editor with a macro facility. But I ruled it out because of the possible large number of files involved.

I don't want to denigrate GoFish or any similar tools, but my inclination would always be to write my own tool for this kind of job - rightly or wrongly.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Apart from thinking that the Code References had that in it, I am inclined to agree.

At least you know what you are getting, probably, depending on how well you do it...

It turns out it was my email client that could search a search if you follow me

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Editors also often have the capability to not only search a current file, but all open files or a directory of files, that's not an exclusive to an IDE or programming a tool. But it's logical you do such a thing as a developer.

Bye, Olaf.

Olaf Doschke Software Engineering
 
I see you've solved this, but for anyone in the future, GoFish has a custom replacement capability. Basically, you write a function that receives the original line as a parameter and replaces it with whatever you return from the function. It's great for situations like this.

I've written about it:
This year, I did a much more complicated custom replacement for a client with this ability.

Tamar
 
I did notice that GoFish could run a UDF, but it was quicker to write my own throw away thing in this instance

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
By coincidence, I was asked this morning to make a "small" change to a large website. The site owner wanted to change the site's background colour. That should have been trivial - except for the fact that, for some reason, the existing background colour had been hard-coded in every page.

I manually added the new colour spec to the CSS file, but I then had to delete it from all the HTML files. I did that using the generic program that I described earlier in this thread (using a similar philosophy to the one that Griff ended up adopting). Doing so took just three lines of code, and the whole job took about ten minutes.

I don't know why I'm mentioning this. It doesn't take the discussion any further forward, but I hope it will be of interest.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
It's a programming conundrum Mike, which is better? Code that takes 10 minutes to write, but an hour to run, or code that takes an hour to write and 10 minutes to run?



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top