G'day marquezc329,

In your config you have lines like key = value and you match the equals ( = ) part with \s=\s. Would key=value, key  =  value, key= value and similar variations be syntactically correct. If so, you may want to consider using \s*=\s* or \s+=\s+ as appropriate.

In a number of places you have code like $var =~ m/.../. While there's nothing actually wrong with this, you don't need the m when using forward slashes as the regexp delimiters, i.e. $var =~ /.../ is fine. Also, when matching $_ you can leave out the variable and the operator: $_ =~ m/.../ can simply be written as /.../. You don't have to use this format but you will see it in other people's code so you should at least be aware of it. All of this is explained in greater detail in Regexp Quote-Like Operators.

I see grizzley picked up on combining a match and substitution. You don't need to capture what you're replacing, so that could be further simplified to:

$line =~ s/^(\s*terminal\s=\s")[^"]+("\s*)$/$1$change$2/;

In getTags() you have m/^\s*names\s=\s{(\s*(.+),?)+\s*/. Here you have nested captures - this is fine in itself; however, as you don't subsequently use either of the captured data both captures are redundant.

Right after this, you have an exceptionally complicated method for stripping double-quotes (and other characters):

if ($line =~ m/^\s*names\s=\s{(\s*(.+),?)+\s*/) { @tags = split ",", $line; @tags = map { if ($_ =~ m/"([^"]+)"/) {$_ = $1} elsif ($_ =~ m/([^\s]+)/) {$_ = $1} } @tags; }

It took me some time to work out what was happening here. I suspect this was where you should have been matching against the previously captured data. I reduced that down to:

$line =~ /^\s*names\s*=\s*{\s*([^}]+)/; (my $names = $1) =~ y/" //d; my @tags = split /,/ => $names;

[y/// and tr/// are synonymous - see Quote-Like Operators for more details.]

That covers all the regexp parts of your code. You might also be interested in YAPE::Regex::Explain (do read the LIMITATIONS section) and Regexp::Debugger.

A consistent coding style, particularly with reference to indentations, would improve the readability of your code: perlstyle offers some advice in this area.

You also asked about "offerings of alternate solutions". I noticed that you're reading the entire config file twice: you indicated that this wasn't the entirety of the code, so maybe you're reading it more than this. You show a terminal setting but also make reference to an editor setting which you don't attempt to change. I've addressed these issues in addition to the regexp points I've already discussed. Here's the code:

#!/usr/bin/env perl use strict; use warnings; # Simulate Tie::File array my @config_file = map { chomp; $_ } <DATA>; print_config('Initial config'); for (@config_file) { $_ = /^\s*terminal\b/ ? change_value(terminal => $_) : /^\s*editor\b/ ? change_value(editor => $_) : /^\s*names\b/ ? get_tags($_) : $_; } print_config('Final config'); sub change_value { my ($key, $line) = @_; print "Current: $line\n"; print 'Change (Enter to keep): '; chomp(my $new_value = <>); if ($new_value) { $line =~ s/^(\s*$key\s*=\s*")[^"]+("\s*)$/$1$new_value$2/; } return $line; } sub get_tags { my $line = shift; $line =~ /^\s*names\s*=\s*{\s*([^}]+)/; (my $names = $1) =~ y/" //d; my @tags = split /,/ => $names; print "TAGS: @tags\n"; return $line; } sub print_config { my $heading = shift; print '=' x 64, "\n"; print "$heading\n"; print '-' x 64, "\n"; print "$_\n" for @config_file; print '=' x 64, "\n"; return; } __DATA__ -- This is used later as the default terminal and editor to run. terminal = "urxvt" editor = "vim" -- Define a tag table which hold all screen tags. tags = { names = { "Main", "WWW", "GIMP", "EMail", 6, 7 },

Here's a couple of sample runs - config values are changed in the second one.

$ pm_regex_review.pl ================================================================ Initial config ---------------------------------------------------------------- -- This is used later as the default terminal and editor to run. terminal = "urxvt" editor = "vim" -- Define a tag table which hold all screen tags. tags = { names = { "Main", "WWW", "GIMP", "EMail", 6, 7 }, ================================================================ Current: terminal = "urxvt" Change (Enter to keep): Current: editor = "vim" Change (Enter to keep): TAGS: Main WWW GIMP EMail 6 7 ================================================================ Final config ---------------------------------------------------------------- -- This is used later as the default terminal and editor to run. terminal = "urxvt" editor = "vim" -- Define a tag table which hold all screen tags. tags = { names = { "Main", "WWW", "GIMP", "EMail", 6, 7 }, ================================================================ $ pm_regex_review.pl ================================================================ Initial config ---------------------------------------------------------------- -- This is used later as the default terminal and editor to run. terminal = "urxvt" editor = "vim" -- Define a tag table which hold all screen tags. tags = { names = { "Main", "WWW", "GIMP", "EMail", 6, 7 }, ================================================================ Current: terminal = "urxvt" Change (Enter to keep): xterm Current: editor = "vim" Change (Enter to keep): emacs TAGS: Main WWW GIMP EMail 6 7 ================================================================ Final config ---------------------------------------------------------------- -- This is used later as the default terminal and editor to run. terminal = "xterm" editor = "emacs" -- Define a tag table which hold all screen tags. tags = { names = { "Main", "WWW", "GIMP", "EMail", 6, 7 }, ================================================================

-- Ken


In reply to Re: Regex help/ Lua parse by kcott
in thread Regex help/ Lua parse by marquezc329

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.