in reply to Searching Formatting and Highlighting Text Problem

5. Remove my old marks

So if I'm understanding correctly, the problem is that the FindAndReplaceAll method does not support backreferences/eval in the replacement expression (like Perl's s/// does) — so something like $text->FindAndReplaceAll(-regexp,-case,'([ACGT])','lc($1)') doesn't work.

Maybe you could instead retrieve the entire contents, do the lowercasing, and then put the modified content back into the widget:

my $s = $text->Contents(); $s =~ tr/ACGT/acgt/; $text->Contents($s);

Replies are listed 'Best First'.
Re^2: Searching Formatting and Highlighting Text Problem
by janusmccarthy (Novice) on Apr 26, 2009 at 12:44 UTC
    You're not understanding correctly, and that's probably my fault. If I retrieve the entire contents and change it there, I've messed the tags that I put in the string to mark where I want to highlight. Here's a better set of sample code. I'm demonstrating my first idea if you set $idea=0. If you go into highlightText2 and uncomment where I've said to break, you can see why I'm not using the original idea, but it does appear better here then when I originally wrote the test code on slightly different text.
    use Tk; $idea = 0; $rawSequence="atggcgacgaaggccgtgtgcgtgctgaagggcgacggcccagtgcagggcatc +atcaatttcgagcagaaggaaagtaatggaccagtgaaggtgtggggaagcattaaaggactgactgaa +ggcctgcatggattccatgttcatgagtttggagataatacagcaggctgtaccagtgcaggtcctcac +tttaatcctctatccagaaaacacggtgggccaaaggatgaagagaggcatgttggagacttgggcaat +gtgactgctgacaaagatggtgtggccgatgtgtctattgaagattctgtgatctcactctcaggagac +cattgcatcattggccgcacactggtggtccatgaaaaagcagatgacttgggcaaaggtggaaatgaa +gaaagtacaaagacaggaaacgctggaagtcgtttggcttgtggtgtaattgggatcgcccaataaaca +ttcccttggatgtagtctgaggcccct"; my $mainWindow = MainWindow->new(); if( $idea) { # Main Window $mainWindow->title("Regex Problem Example 1"); $mainWindow->minsize(qw(500 500)); #Sets Minimum Size - note lack + of comma $mainWindow->geometry('+500+200'); #Sets Position - note lack of +comma $mainWindow->optionAdd('*font'=>'Courier 10'); $ROText = $mainWindow->Scrolled('ROText', -scrollbars=>'osoe'); $formattedSequence = formatSequence($rawSequence); $ROText->Insert($formattedSequence); $ROText->pack; highlightText($ROText, "gca"); } else { # Main Window $mainWindow->title("Regex Problem Example 2"); #Sets Title $mainWindow->minsize(qw(500 500)); #Sets Minimum Size - note lack + of comma $mainWindow->geometry('+500+200'); #Sets Position - note lack of +comma $mainWindow->optionAdd('*font'=>'Courier 10'); $ROText = $mainWindow->Scrolled('ROText', -scrollbars=>'osoe'); $formattedSequence = searchAndFormatSequence($rawSequence); $ROText->Insert($formattedSequence); $ROText->pack; #This works, but I can't make Uppercase->Lowercase #without removing the tags. highlightText2($ROText, "[A-Z]+"); } MainLoop(); sub highlightText { my ($widget, $searchString) = @_; #alter search string - HOW? # Create a tag to configure the text $widget->tagConfigure('foundtag', -foreground => "white", -background => "red"); $widget->FindAll(-regex, -nocase, $searchString); if ($widget->tagRanges('sel')) { my %startfinish = $widget->tagRanges('sel'); foreach(sort keys %startfinish) { $widget->tagAdd("foundtag", $_, $startfinish{$_}); } $widget->tagRemove('sel', '1.0', 'end'); } } sub highlightText2 { my ($widget, $searchString) = @_; #alter search string - HOW? # Create a tag to configure the text $widget->tagConfigure('foundtag', -foreground => "white", -background => "red"); $widget->FindAll(-regex, -case, $searchString); if ($widget->tagRanges('sel')) { my %startfinish = $widget->tagRanges('sel'); foreach(sort keys %startfinish) { $widget->tagAdd("foundtag", $_, $startfinish{$_}); } $widget->tagRemove('sel', '1.0', 'end'); } #UNCOMMENT TO BREAK! Doesn't like a regex in the replace string #$widget->FindAndReplaceAll(-regex, -case, "G", "g"); #$widget->FindAndReplaceAll(-regex, -case, "C", "c"); #$widget->FindAndReplaceAll(-regex, -case, "A", "a"); } sub searchAndFormatSequence { #I search the sequence and change any gca in the sequence to GCA t +hen #format the sequence, the end result of which is return " 1 atggcgacga aggccgtgtg cgtgctgaag ggcgacggcc cagt +GCAggG CAtcatcaat 61 ttcgaGCAga aggaaagtaa tggaccagtg aaggtgtggg gaaGCAttaa aggac +tgact 121 gaaggcctGC Atggattcca tgttcatgag tttggagata atacaGCAgg ctgta +ccagt 181 GCAggtcctc actttaatcc tctatccaga aaacacggtg ggccaaagga tgaag +agagG 241 CAtgttggag acttggGCAa tgtgactgct gacaaagatg gtgtggccga tgtgt +ctatt 301 gaagattctg tgatctcact ctcaggagac cattGCAtca ttggccGCAc actgg +tggtc 361 catgaaaaaG CAgatgactt ggGCAaaggt ggaaatgaag aaagtacaaa gacag +gaaac 421 gctggaagtc gtttggcttg tggtgtaatt gggatcgccc aataaacatt ccctt +ggatg 481 tagtctgagg cccct"; } sub formatSequence { #I do some really neat formatting here the end result of which is. +.. return " 1 atggcgacga aggccgtgtg cgtgctgaag ggcgacggcc cagt +gcaggg catcatcaat 61 ttcgagcaga aggaaagtaa tggaccagtg aaggtgtggg gaagcattaa aggac +tgact 121 gaaggcctgc atggattcca tgttcatgag tttggagata atacagcagg ctgta +ccagt 181 gcaggtcctc actttaatcc tctatccaga aaacacggtg ggccaaagga tgaag +agagg 241 catgttggag acttgggcaa tgtgactgct gacaaagatg gtgtggccga tgtgt +ctatt 301 gaagattctg tgatctcact ctcaggagac cattgcatca ttggccgcac actgg +tggtc 361 catgaaaaag cagatgactt gggcaaaggt ggaaatgaag aaagtacaaa gacag +gaaac 421 gctggaagtc gtttggcttg tggtgtaatt gggatcgccc aataaacatt ccctt +ggatg 481 tagtctgagg cccct"; }

      Can't you just do the lowercasing before you apply the ranges (using the uppercase approach you outlined)?  The tag positions in %startfinish would still be valid, as the case has no influence on length...

      my %startfinish = $widget->tagRanges('sel'); # undo uppercase my $s = $widget->Contents(); $s =~ tr/A-Z/a-z/; $widget->Contents($s); foreach(sort keys %startfinish) { $widget->tagAdd("foundtag", $_, $startfinish{$_}); }

      That would at least highlight all (lowercased) subsequences. But I'm still not entirely sure what the ultimate objective is... Is it just the highlighting?

        That worked! Thank you much! To answer your question, the first goal is basically highlighting. What I eventually want to do with it is let a user type in the starting characters of a known piece of the sequence (which he gets from another source) until he gets one highlighted area. Then do the same thing for the last part of the sequence, then be able to take the area between the two highlighted sequences and do what's called a Blast, which tries to find that sequence in another species.