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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

searching for a variable in a regular expression

Status
Not open for further replies.

cb49747

MIS
Apr 23, 2002
181
0
0
US
Here is the problem. I have various queries stored which grab different information from the database. Associated with each query is some text. This text is different for each query. In this text is information that tell which fields to show and where.

an example of this text would be

$text = "please show this field [[showfield4]] and then show this field [[showfield5]]";

When the query runs say it finds 10 matches. the info in these fields is different for each match.

What I want to do is do a regular expression that will search this text and replace the [[showfield3]] with $alert[3]

This is what I currently have but doesn't work.

while (@alert = $run_ealert->fetchrow_array) {
$temp_text = $ealert_text;
for ($c = 0; $c <= $#alert; $c++) {
$temp_text =~ s/[[showfield$c]]/$alert[$c]/g;
print $temp_text;

I'm not getting a match.

Any help would be greatly appreciated.

Thanks in advance.
 
No time to look at it in detail now, but note that [ and ] mean something in a regex, and will need to be escaped. Or use \Q....\E to have them treated as literals

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
I have changed to this and still no go.


while (@alert = $run_ealert->fetchrow_array) {
$temp_text = $ealert_text;
for ($c = 0; $c <= $#alert; $c++) {
$temp_text =~ s/\[\[showfield($c)\]\]/$alert[$c]/g;
print $temp_text;
 
are you trying to substitute [[showfiled1]] with the value contained in $alert[1] ?? or literally '$alert[1]' ?

 
I'm trying to substitute [[showfield1]] with the value contained in $alert[1].

I made a few changes and got this to work.
Code:
$run_ealert = $dbh->prepare( $ealert_query );
 $run_ealert->execute();
  $total_emails = 0;
   while (@alert = $run_ealert->fetchrow_array) {	  
    $total_emails ++;
    for ($c = 0; $c <= $#alert; $c++) { $ealert_text =~ s/ShowField${c}/$alert[$c]/g;}
    SendEalert($alert[1],$ealert_text,$alert[2]);
    $emaillist .= "$alert[0] -- $alert[1] -- $alert[2] -- $h ";	  
   }

however this will substitute the ShowField1 with the value $alert[1] but only for the first loop. Any subsequent records get the first records data (this is because ShowField1 is no longer in the text as it has be changed to the value.).

Hence I added the line $temp_text = $ealert_text and made the appropriate change in the SendEalert() call in the code below. However it seems to reset prior to the subroutine running. If I do a print of $temp_text durring the for loop it prints the correct data, but the ealert has the original data.

Code:
$run_ealert = $dbh->prepare( $ealert_query );
 $run_ealert->execute();
  $total_emails = 0;
   while (@alert = $run_ealert->fetchrow_array) {	  
    $total_emails ++;
    $temp_text = $ealert_text;
    for ($c = 0; $c <= $#alert; $c++) { $ealert_text =~ s/ShowField${c}/$alert[$c]/g;}
    SendEalert($alert[1],$temp_text,$alert[2]);
    $emaillist .= "$alert[0] -- $alert[1] -- $alert[2] -- $h ";	  
   }

also to clarify I removed the [[ and ]] from the original text as thought that might be messing up the reg expression.

any ideas
 
Just to clarify in the second bit of code I have also changed the $ealert_text in the for loop to $temp_text so the code looks like this:

$temp_text =~ s/ShowField${c}/$alert[$c]/g;

just forgot to add that in the first post.
 
Ok, this little snip I wrote works... maybe try it?

Code:
$text = "please show this field [[showfield4]] and then show this field [[showfield5]]";

@alert = ("first", "second", "third", "fourth", "fith", "sixth", "seventh");

        for ($c = 0; $c <= $#alert; $c++) {
        $text =~ s/\[\[showfield$c\]\]/\$alert\[$c\]/g;

        $text =~ s/(\$\w+\[[0-9]+\])/$1/eeg;

        }

print "$text";
 
btw, my code was _before_ you took teh extra brackets out.
 
Plunkett,

Thanks. This works. However when I run it in a while statement as it needs to run multiple times I need to get the text to reset back to the original text.

Also could you give me a brief explanation on what is happening on this line.

$text =~ s/(\$\w+\[[0-9]+\])/$1/eeg;
 
so, $temp_text doesn't change in the scope of this problem, but you copy it to $ealert_text and then dump $ealert_text off to a sub each iteration, right?


as for $text =~ s/(\$\w+\[[0-9]+\])/$1/eeg;

s/(whatever)/$1/eeg;

This searches the entire line for whatever (or multiple instances of it) and then substitutes it _after_ evaluating it.

\$ means $
\$\w+ means $ + one or more letter
\$\w+\[ means $ + one or more letter + [
\$\w+\[[0-9]+ means $ + one or more letter + [ + one or more number
\$\w+\[[0-9]+\] means $ + one or more letter + [ + one or more number + ]

... basically this matches something like $alert[3] and then evaluates it and then substitutes the evaluated piece back in.
 
the problem here:

Code:
$text = "please show this field [[showfield4]] and then show this field [[showfield5]]";

@alert = ("first", "second", "third", "fourth", "fith", "sixth", "seventh");

        for ($c = 0; $c <= $#alert; $c++) {
        $text =~ s/\[\[showfield$c\]\]/\$alert\[$c\]/g;

        $text =~ s/(\$\w+\[[0-9]+\])/$1/eeg;

        }

print "$text";

$text is one line so you need to increment $c while processing the same line. You are processing an array and increment $c only when you go to the next loop. So if you are on the loop where $c is 4 the next pattern that has 5 as the marker for the pattern you want to substitute will not be found. What I think you want to do is something like this:

Code:
$text = "please show this field [[showfield4]] and then show this field [[showfield5]]";
@alert = ("first", "second", "third", "fourth", "fith", "sixth", "seventh");
$text =~ s/\[\[showfield(\d+)\]\]/$alert[$1-1]/g;
print "$text";

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
plunkett,

Thanks for the explanation. Appreciate it.

Your above question is correct but reversed. $ealert_text does not change and the $temp_text should reset to $ealert_text then go thru the for loop and pass off to the sub on each iteration.

 
Kevin,

Thanks.

Your seems to work as well. appreciate it.

The problem I have now is that I need it to run for every record I find.

Here is what I have so far.

Code:
$run_ealert = $dbh->prepare( $ealert_query );
 $run_ealert->execute();
  $total_emails = 0;
   while (@alert = $run_ealert->fetchrow_array) {	  
    $total_emails ++;
    $temp_text = $ealert_text;
    for ($c = 0; $c <= $#alert; $c++) { $temp_text =~ s/ShowField${c}/$alert[$c]/g;}
    SendEalert($alert[1],$temp_text,$alert[2]);
   }

Code:
$run_ealert = $dbh->prepare( $ealert_query );
 $run_ealert->execute();
  $total_emails = 0;
   while (@alert = $run_ealert->fetchrow_array) {	  
    $total_emails ++;
    for ($c = 0; $c <= $#alert; $c++) { $ealert_text =~ s/ShowField${c}/$alert[$c]/g;}
    SendEalert($alert[1],$ealert_text,$alert[2]);	  
   }

The second bit of code works but only for one instance all subsequent instances or records have the data from the first.

The first bit of code, which I thought would work, gives me the code prior to the for loop ie still has the ShowField4 in it rather than the data.

I have tried the above suggestions for the below line.
Code:
    for ($c = 0; $c <= $#alert; $c++) { $ealert_text =~ s/ShowField${c}/$alert[$c]/g;}
and they all seem to work, not sure if one is better than the other. but can not get any to work for multiple records or instances.
 
in your code you have $ealert_text, what is that? In my code I showed that you do not need the "for "loop.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
$ealert_text is my text that contains the ShowField4 and ShowField5 and so on.

I then run a query to get the data put it in the @alert array.

It is this data that is different for every record it finds.

I then set the a new var $temp_text = to $ealert_text so as to not change the original text.

I then run my reg expression on the $temp_text and then send that to my SendEalert() Subroutine.

The regular expression seems to work fine but it does not send the changed text to the sub.

I wonder if there is an order in which perl handles these processes? Does it place the text in the sub prior to running the for loop? At the start of this thread I had problems with the reg expression that is now working I just need to get it to run for every record.

Thanks for your help.
 
I am still confused, maybe this is what you want to do:

Code:
$run_ealert = $dbh->prepare( $ealert_query );
$run_ealert->execute();
$total_emails = 0; [b]#<---what is this for?[/b]
while (@alert = $run_ealert->fetchrow_array) {      
    $total_emails++; [b]#<---what is this for?[/b]
    $temp_text = $ealert_text;[b]#<-- this makes no sense to me. See below.[/b]
    $temp_text =~ s/\[\[ShowField(\d+)\]\]/$alert[$1-1]/g;
    SendEalert($alert[1],$temp_text,$alert[2]);
}

Unless $ealert_text is getting changed to a new value all you keep doing is assigning the same value to $temp_text over and over.

Note you have [red]S[/red]how[red]F[/red]ield in the above code. An uppercase S and F, that is important. If the case is different add the "i" (case insensitive) option to the end of the regexp where the "g" is.

Trying to help with a part of a larger program that appears to not be written using the "strict" pragma is not something anyone will want to put much effort into helping you with.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
ok,

Problem resolved. I was not print the proper var in the sub routine. My Mistake.

I do appreciate all the help with the regular expression.

Great bunch here.
 
Just to clarify what I was doing
Code:
$total_emails = 0; #<---what is this for?
this is setting the number of emails to 0

Code:
$total_emails++; #<---what is this for?
This adds one for each email(ie alert) going out.

Code:
$temp_text = $ealert_text;#<-- this makes no sense to me.
my text for the alert or email is held in this variable ($ealert_text). In this text is the ShowField4 (or what ever number of field I want to show based on the alert going out. This needs to be changed to $alert[4] which holds that fields data, thus the regular expression. However if I run it on $ealert_text I have now changed the text and can no longer search for the ShowField4 because it is no longer there, but rather the data for the previous alert. Thus I must use a temp var ($temp_text) to hold the text and then reset it every time it loops in the while statement.

This may not be the most efficient way to do this but it does work. I would greatfull as I'm still learning perl, to know of a more efficient way of doing it if there is one.

Thanks for all your help.
See below.
 
please put your head up against your computer monitor so I can give it a whack.... [hammer]

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top