Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 226
  • Last Modified:

Question for a Regex in split

Hi,

can anyone tell me a regex which I can use to split
lines where fields are separated by a ; if this is
not within two paired double quotes?

Example:

Field 1;Field 2;"Field 3a;Field 3b";"Field 4a;Field 4b"

I want to get:

Field 1
Field 2
Field 3a;Field 3b
Field 4a;Field 4b

I have to use split as it is not known to me how many
fields there are and where a semicolon is included in
double quotes.

Thanks for your help,
Kai.
0
kaijen
Asked:
kaijen
  • 3
1 Solution
 
ozoCommented:
@fields=/((?:"[^"]*"|[^;])+)/g;
0
 
ozoCommented:
perldoc -q split
Found in perlfaq4.pod

How can I split a [character] delimited string except when inside [character]? (Comma-separated files)

Take the example case of trying to split a string that is comma-separated
into its different fields.  (We'll pretend you said comma-separated, not
comma-delimited, which is different and almost never what you mean.) You
can't use C<split(/,/)> because you shouldn't split if the comma is inside
quotes.  For example, take a data line like this:

    SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped"

Due to the restriction of the quotes, this is a fairly complex
problem.  Thankfully, we have Jeffrey Friedl, author of a highly
recommended book on regular expressions, to handle these for us.  He
suggests (assuming your string is contained in $text):

     @new = ();
     push(@new, $+) while $text =~ m{
         "([^\"\\]*(?:\\.[^\"\\]*)*)",?  # groups the phrase inside the quotes
       | ([^,]+),?
       | ,
     }gx;
     push(@new, undef) if substr($text,-1,1) eq ',';

If you want to represent quotation marks inside a
quotation-mark-delimited field, escape them with backslashes (eg,
C<"like \"this\"">.  Unescaping them is a task addressed earlier in
this section.

Alternatively, the Text::ParseWords module (part of the standard perl
distribution) lets you say:

    use Text::ParseWords;
    @new = quotewords(",", 0, $text);

0
 
kaijenAuthor Commented:
Thanks alot!

This works. I only have to work out how to strip the
doublequotes. But this sounds like a good homework.

Please state this as an answer and I'll give you the
points!

Best regards,
Kai.
0
 
ozoCommented:
# If the quotes are not part of the field, does that mean that you'll never see anything like
# Field 1;;"Field" "3a;" "Field 3b";Field 4a";"Field 4b
#If not then something like this may work for you:
@fields = grep length,split /;|"([^"]*)"/;
#or
push @fields,$+  while /(?:"([^"]*)|([^;]+))[^;]*;?/g;
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now