http://qs1969.pair.com?node_id=231338

Willman023 has asked for the wisdom of the Perl Monks concerning the following question:

I just wrote a short script to parse out &lt;/&gt; and replace with </> in a DB(code below). But for some reason its not matching every symbol. For example, on the 12th line of a description I have:

icon or choose the Results-&gt;View Plotfiles you

and for another I have:

<br>&lt;/pre&gt;<br>&lt;img src=http://blah.microsoft.com/analog_sc/bp +/_lessons_learned/2788_1.jpg&gt;<br>&lt;br&gt;<br>&lt;img

How can I match any &lt; and &gt;?
Thanks!

#!/opt/perl/bin/perl -w use Win32::ODBC; use strict; # MAKE CONNECTION AND QUERY ACCESS DATABASE my $connstring = "EPI_DB"; my $db = new Win32::ODBC($connstring) or die $!; $db->Sql("SELECT entry_id, description FROM entry"); my $description; my $entry_id; while ($db->FetchRow()) { $description= $db->Data('description'); $entry_id = $db->Data('entry_id'); tagremover($description); my $db2 = new Win32::ODBC($connstring) or die $!; $db2->Sql("UPDATE entry SET description='$description' WHERE entry +_id=$entry_id"); } print "Cleaning Complete\n"; $db->Close(); # FUNCTION TO CLEAN TAGS FROM DATABASE sub tagremover { $_[0] =~ s/&lt;/</g; # REPLACES ALL HTML < SYMBOLS IN DB $_[0] =~ s/&gt;/>/g; # REPLACES ALL HTML > SYMBOLS IN DB }
bW

Replies are listed 'Best First'.
Re: Regex not matching all in DB
by zakb (Pilgrim) on Jan 30, 2003 at 16:08 UTC

    First of all, my initial instinct is to recommend you have a look at HTML::Entities, which will save you from expanding tagremover ad infinitum as you discover you have more entities to replace.

    As for your question, the only thing I can think of is that Win32::ODBC->Data does not return a modifiable string reference. Hopefully, someone more enlightened can help!

Re: Regex not matching all in DB
by Wonko the sane (Deacon) on Jan 30, 2003 at 16:25 UTC
    I agree that you are probably better off using HTML::Entities
    The code you have should work for what you are trying to do.
    The following snippet works as expected on your test line.
    #!/usr/local/bin/perl -w use strict; my $line = q{<br>&lt;/pre&gt;<br>&lt;img src=http://blah.microsoft.com +/analog_sc/bp/_lessons_learned/2788_1.jpg&gt;<br>&lt;br&gt;<br>&lt;im +g}; print qq{LINE:[$line]\n}; tagremover( $line ); print qq{LINE:[$line]\n}; sub tagremover { $_[0] =~ s/&lt;/</g; $_[0] =~ s/&gt;/>/g; }
    Outputs:
    LINE:[<br>&lt;/pre&gt;<br>&lt;img src=http://blah.microsoft.com/analog +_sc/bp/_lessons_learned/2788_1.jpg&gt;<br>&lt;br&gt;<br>&lt;img] LINE:[<br></pre><br><img src=http://blah.microsoft.com/analog_sc/bp/_l +essons_learned/2788_1.jpg><br><br><br><img]
    What are you getting in your $description var after the replacement? DOes your data have Newlines in it?

    Wonko

      Thanks alot guys! Its not that my regex doesn't work at all it does get some, just not when its -&gt; or <br>&lt I saw no need to escape anything in my regex the & and semicolon aren't special at all. I guess I'll try HTML::Entities as suggested instead of writing a hundred regex's.

      bW
      Perl - the breakfast of Champions!

Re: Regex not matching all in DB
by graff (Chancellor) on Jan 31, 2003 at 05:46 UTC
    Well, I really don't think it has anything to do with your regexes; you say they are working on some cases, and since that is true, they should be working on all cases -- that is, all cases that really do match those regexes.

    How closely have you looked at the content of the strings you get back from that database connection? I would suggest that there may be some extra characters in there that aren't visible if you're just using a typical console window or browser to view them. Open an output file -- and use binmode() to make sure nothing gets "interpreted" on output -- and write the offending text before and after the call to tagremover. Then look at it with any hex-mode viewer. It may be that some of those unaltered entities have "invisible" garbage characters thrown in somehow.

    One other point, on a different topic:

    while ($db->FetchRow()) { ... my $db2 = new Win32::ODBC($connstring) or die $!; ... }
    I haven't used ODBC personally (I'm in a solaris/oracle shop), but it strikes me as wrong to be doing this connection thing on every iteration of the "while()" loop. Aren't you using the same database here as in the initial connection? Wouldn't the original connection be persistent and available for further queries/updates until you explicitly close it or exit? (I could be wrong about this, but if the repeated open is unnecessary, removing it could save you a lot of overhead.)

    Good luck with the text content.

Re: Regex not matching all in DB
by JamesNC (Chaplain) on Jan 30, 2003 at 16:18 UTC
    you need to escape some stuff...try:
    $_[0] =~ s/\&lt\;/</g; $_[0] =~ s/\&gt\;/>/g;
      Huh? You only need to escape characters that have a special meaning for the regex machine. Care to point out the meaning of ;?

      And could you also write a doc patch? perlre.pod doesn't document the special behaviour of the semi-colon.

      Abigail