Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
Think about Loose Coupling
 
PerlMonks

Matching escaped quoted strings

by jmcnamara (Monsignor)
 | Log in | Create a new user | The Monastery Gates | Super Search | 
 | Seekers of Perl Wisdom | Meditations | PerlMonks Discussion | 
 | Obfuscation | Reviews | Cool Uses For Perl | Perl News | Q&A | Tutorials | 
 | Poetry | Recent Threads | Newest Nodes | Donate | What's New | 

on Feb 19, 2004 at 17:40 UTC ( #330280=perlquestion: print w/ replies, xml ) Need Help??
jmcnamara has asked for the wisdom of the Perl Monks concerning the following question:


Here is a problem that may be harder or simpler than it looks.

The task is to extract double quoted strings from another string. For the string

'"foo" & "bar"'

the matched strings would be "foo" and "bar" including the quotes.

The thing that makes this a little tricky is that double quotes in the quoted string are escaped using a pair of quotes. I think this escape format comes from Basic. Thus, the string " He said "maybe" " would be escaped as follows:

'" He said ""maybe"" "'

This leads to some nice pathological cases such as '""""""""""' and '" """&" """'

Here is a test framework if you care to bend your brain to this puzzle. I'll post my own answer later.

Problem. Write a function find_quote() which takes a string and adds <> around the double quoted strings.

For example

'"foo" & "bar"' -> '<"foo"> & <"bar">'

Double quotes within the string are escaped as a pair of double quotes. The quotes will always be balanced. Apart from double quotes there can be any arbitrary characters before or after the strings. The test below should demonstrate the types of string to expect.

#!/usr/bin/perl -w use strict; use Test::More 'no_plan'; # Test input and target output my %strings = ( '' => '', '""' => '<"">', '""""' => '<"""">', '""&""&""&""&""' => '<"">&<"">&<"">&<"">&<"">', '""""""""""' => '<"""""""""">', '""""&""""' => '<"""">&<"""">', '"""&"""' => '<"""&""">', '"foo"&"bar"' => '<"foo">&<"bar">', ' "foo" & "bar" ' => ' <"foo"> & <"bar"> ', '" "' => '<" ">', '" "" "' => '<" "" ">', '" """&" """' => '<" """>&<" """>' , '" "" "' => '<" "" ">', '" "" "&" "" "' => '<" "" ">&<" "" ">', '" "" & "" "' => '<" "" & "" ">', '""&""""' => '<"">&<"""">', ' "" ' => ' <""> ', ' """" ' => ' <""""> ', ' ""&""&""&""&"" ' => ' <"">&<"">&<"">&<"">&<""> + ', ' """""""""" ' => ' <""""""""""> ', 'test("foo","bar")' => 'test(<"foo">,<"bar">)', ); # Add your code here sub find_quote { my $str = $_[0]; # Broken example $str =~ s/(".*?")/<$1>/g; return $str; } # Run the tests while (my($input, $result) = each %strings) { is(find_quote($input), $result, "for string:\t" . "'$input'"); }

--
John.

Comment on Matching escaped quoted strings
Select or Download Code
•Re: Matching escaped quoted strings
by merlyn (Sage) on Feb 19, 2004 at 17:43 UTC
Re: Matching escaped quoted strings
by Abigail-II (Bishop) on Feb 19, 2004 at 17:54 UTC
    use Regexp::Common; s/$RE{delimited}{-delim => '"'}{-esc => '"'}{-keep}/<$1>/g;

    Abigail

      Regexp::Common is delightful; that produces the quite nice: (?-xism:((\")([^\"]*(?:(?:\"\")[^\"]*)*)(\")))
Re: Matching escaped quoted strings
by jmcnamara (Monsignor) on Feb 19, 2004 at 21:15 UTC

    Nice answers. merlyn's in particular.

    I was definitely overthinking or underthinking the problem. Here is my take for the record.

    sub find_quote { my $str = $_[0]; my $c; $str =~ s/( (?{$c = 1}) ".*?" (?{$c++}) (?(?{$c % 2 == 0})(?!")|^) ) /<$1>/xg; return $str; }

    --
    John.

Login:
Password
remember me
What's my password?
Create A New User

Node Status?
node history
Node Type: perlquestion [id://330280]
Approved by Tomte
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (18)
Corion
GrandFather
shmem
tirwhan
holli
atcroft
kennethk
MidLifeXis
thezip
Eyck
clinton
Utilitarian
bichonfrise74
ssandv
ramlight
MikeDexter
im2
fbicknel
As of 2010-02-09 20:19 GMT
Sections?
The Monastery Gates
Seekers of Perl Wisdom
Meditations
PerlMonks Discussion
Categorized Q&A
Tutorials
Obfuscated Code
Perl Poetry
Cool Uses for Perl
Perl News
Information?
PerlMonks FAQ
Guide to the Monastery
What's New at PerlMonks
Voting/Experience System
Tutorials
Reviews
Library
Perl FAQs
Other Info Sources
Find Nodes?
Nodes You Wrote
Super Search
List Nodes By Users
Newest Nodes
Recently Active Threads
Selected Best Nodes
Best Nodes
Worst Nodes
Saints in our Book
Leftovers?
The St. Larry Wall Shrine
Offering Plate
Awards
Craft
Snippets Section
Code Catacombs
Quests
Editor Requests
Buy PerlMonks Gear
PerlMonks Merchandise
Planet Perl
Perlsphere
Use Perl
Perl.com
Perl 5 Wiki
Perl Jobs
Perl Mongers
Perl Directory
Perl documentation
CPAN
Random Node
Voting Booth?

What level of existential comfort do you require?

Palace
Executive suite at the best hotel
Regular hotel in a decent part of town
Motel
Boarding house
Sleeping Bag on Couch in Basement
Any port in a storm
Camping under the freeway overpass
Jail
Other

Results (279 votes), past polls