Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Oneliner with substring trimming and padding

by Neighbour (Friar)
on Jul 17, 2012 at 11:59 UTC ( #982210=perlquestion: print w/replies, xml ) Need Help??
Neighbour has asked for the wisdom of the Perl Monks concerning the following question:

I'm looking for a way to trim specific characters from the beginning of a substring at a specified location,length, and add (and this is the hard part) an amount of <padding character>s equal to the trimmed length to the end of the substring in order to keep the entire string (which is part of a fixed-length datastream) intact.
If the trimmed character is the same as the padding character, this bit of code does the trick:
perl -pi -e 'substr($_,589,35) =~ s/(\s*)(\w+)*/$2$1/ if /^(.{589})(\s +{1,34})/' file.txt
However, when the padding character is different from the trimmed character, $1 won't suffice :).
I've tried
perl -pi -e 'substr($_,589,35) =~ s/(0*)(\w+)*/$2($?{ ' ' x length($1) + })/ if /^(.{589})(0{1,34})/' file.txt
but that doesn't seem to work (maybe because $? is only allowed in the "matching"-part of a regex?
Any help is welcome :)

Edit: Using ''s inside a ''-command isn't useful, replacing them with ""s made it go, but not quite right.
perl -pi -e 'substr($_,589,35) =~ s/(0*)(\w+)*/$2($?{ " " x length($1) + })/ if /^(.{589})(0{1,34})/' file.txt
The 00 that gets trimmed gets replaced by ()with this code.

Replies are listed 'Best First'.
Re: Oneliner with substring trimming and padding
by grizzley (Chaplain) on Jul 17, 2012 at 12:07 UTC

    Try eval (I've added needed additional parens around second matching group):

    perl -pi -e 'substr($_,589,35) =~ s/(0*)((\w+)*)/$2.(' ' x length($1))/e if /^(.{589})(0{1,34})/' file.txt
      Ahh, /e makes all the difference...sneaky little bugger isn't explicitly documented in Modifiers, but is mentioned in Regexp Quote Like Operators (which I didn't look at until now).
      Thanks a lot :)

        It's not documented in perlre because perlre is ridiculously pedantic. The /e doesn't modify the regular expression; it modifies the replacement text.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Oneliner with substring trimming and padding
by Ratazong (Monsignor) on Jul 17, 2012 at 12:09 UTC

    What about the following approach:

    1. adding a "maximum number" of padding-characters at the end of your substring
    2. cutting the substing back to the desired number of characters
    That way you avoid calculating the real number of needed padding-characters

    Just an idea. Rata

      Sure, but how do you do this in an inplace-edit oneliner? :)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://982210]
Approved by Ratazong
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2017-03-26 10:10 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (314 votes). Check out past polls.