Re: Parsing a text file with mutuple seperator

[email protected] ("Brad Baxter") Tue, 8 Apr 2008 08:39:20 -0400
Newsgroups perl.scripts
Message-ID <[email protected]>
------=_Part_19711_12831914.1207658360551
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

If I were you, I'd use Text::ParseWords::parse_line()

On Mon, Apr 7, 2008 at 9:11 PM, <[email protected]> wrote:

> Hi all,
>
> I am writing a perl script to parse a file. The data in the file is
> seperated by space/tab. However, certain fields may be empty or
> consist of mutiple words and are double quoted and this makes it
> difficut for me to do a split.
>
> Example of data:
> ""   "This is 2nd field"
> 3                                                                  4
> 1    2
> ""                                                                 4
> 1    2                           "The field may consist of (meta)
> characters"   ""
>
>
> What I am doing is as such:
>   while ($line=~/(".*?")/) {;             <- Loops until all double-
> quoted string is replaced
>      $line=~s/""/__EMPTY__/g;
>      $tmp1=$1;
>      $tmp2=$1;
>      $tmp1=~s/"//g;
>      $tmp1=~s/ /__SPACE__/g;
>      $tmp2=~s/([\(\)])/\\$1/g;
>      $line=~s/$tmp2/$tmp1/;            <- needs to replace meta-
> characters in $tmp2
>   }
>   @tmp=split /\s+/, $line;
>   foreach $i (0..$#tmp) {
>      $tmp[$i]=~s/__SPACE__/ /g;
>      $tmp[$i]=~s/__EMPTY__//g;
>      // Store data
>   }
>
>
> Substitue "" with __EMPTY__
> While line matches ".*?" (non-greedy match), remember the content
> between the quotes.
> Assign this content to $tmp1 and $tmp2. Remove " from $tmp1, Replace '
> ' with __SPACE__.
> Replace metacharacters of $tmp2 with escape, ie (meta) to \(meta\).
> Substition of $tmp2 with $tmp1 (non-global).
> Do a split /\s+/,
> Replace __EMPTY__ with empty string
> Replace __SPACE__ with " ".
>
> Does you one have a neater and more efficient way either by split of
> regexp?
>
>
> Thanks
> Shu Teng
>
>

------=_Part_19711_12831914.1207658360551
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

If I were you, I&#39;d use Text::ParseWords::parse_line()<br><br><div class="gmail_quote">On Mon, Apr 7, 2008 at 9:11 PM,  &lt;<a href="mailto:[email protected]">[email protected]</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi all,<br>
<br>
I am writing a perl script to parse a file. The data in the file is<br>
seperated by space/tab. However, certain fields may be empty or<br>
consist of mutiple words and are double quoted and this makes it<br>
difficut for me to do a split.<br>
<br>
Example of data:<br>
&quot;&quot; &nbsp; &quot;This is 2nd field&quot;<br>
3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4<br>
1 &nbsp; &nbsp;2<br>
&quot;&quot; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4<br>
1 &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;The field may consist of (meta)<br>
characters&quot; &nbsp; &quot;&quot;<br>
<br>
<br>
What I am doing is as such:<br>
 &nbsp; while ($line=~/(&quot;.*?&quot;)/) {; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- Loops until all double-<br>
quoted string is replaced<br>
 &nbsp; &nbsp; &nbsp;$line=~s/&quot;&quot;/__EMPTY__/g;<br>
 &nbsp; &nbsp; &nbsp;$tmp1=$1;<br>
 &nbsp; &nbsp; &nbsp;$tmp2=$1;<br>
 &nbsp; &nbsp; &nbsp;$tmp1=~s/&quot;//g;<br>
 &nbsp; &nbsp; &nbsp;$tmp1=~s/ /__SPACE__/g;<br>
 &nbsp; &nbsp; &nbsp;$tmp2=~s/([\(\)])/\\$1/g;<br>
 &nbsp; &nbsp; &nbsp;$line=~s/$tmp2/$tmp1/; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;- needs to replace meta-<br>
characters in $tmp2<br>
 &nbsp; }<br>
 &nbsp; @tmp=split /\s+/, $line;<br>
 &nbsp; foreach $i (0..$#tmp) {<br>
 &nbsp; &nbsp; &nbsp;$tmp[$i]=~s/__SPACE__/ /g;<br>
 &nbsp; &nbsp; &nbsp;$tmp[$i]=~s/__EMPTY__//g;<br>
 &nbsp; &nbsp; &nbsp;// Store data<br>
 &nbsp; }<br>
<br>
<br>
Substitue &quot;&quot; with __EMPTY__<br>
While line matches &quot;.*?&quot; (non-greedy match), remember the content<br>
between the quotes.<br>
Assign this content to $tmp1 and $tmp2. Remove &quot; from $tmp1, Replace &#39;<br>
&#39; with __SPACE__.<br>
Replace metacharacters of $tmp2 with escape, ie (meta) to \(meta\).<br>
Substition of $tmp2 with $tmp1 (non-global).<br>
Do a split /\s+/,<br>
Replace __EMPTY__ with empty string<br>
Replace __SPACE__ with &quot; &quot;.<br>
<br>
Does you one have a neater and more efficient way either by split of<br>
regexp?<br>
<br>
<br>
Thanks<br>
Shu Teng<br>
<br>
</blockquote></div><br>

------=_Part_19711_12831914.1207658360551--