chessgui has asked for the wisdom of the Perl Monks concerning the following question:

I'm quite familiar with reg exps as far as parsing is concerned. But here is a substitution problem (which I've read somewhere can be done in one go using reg exps but I can't remember how):

Substitute all decimal numbers in a string with that many hyphens as the numbers say. (This problem comes from translating fen strings in chess to printable positions.)

So 'p1r4k/8' should be translated to 'p-r----k/--------'.

Replies are listed 'Best First'.
Re: A silly reg exp question
by tobyink (Canon) on Jan 16, 2012 at 14:24 UTC
    s{ (\d+) } { '-' x $1 }gex;

    Update: I'll add that this allows arbitrary integers in the string, including integers with two or more digits. Assuming that you're sticking to standard sized chess boards, the following is probably sufficient...

    s{ ([1-8]) } { '-' x $1 }gex;
      Tested: OK. This is the most general and readable code so I will use this in my prog.
Re: A silly reg exp question
by Corion (Patriarch) on Jan 16, 2012 at 14:13 UTC

    You might want to take a look at the /e modifier for regular expressions in perlre.

      In perlre the 'e' modifier is not explained. You should have directed me to perlop. Now it is clear that /e rather than replacing the match with a string it replaces it with an (e)xpression evaluated.
Re: A silly reg exp question
by JavaFan (Canon) on Jan 16, 2012 at 14:37 UTC
    A couple of ways (all untested):
    s/([1-8])/"-" x $1/eg; s/1/-/g, s/2/--/g, s/3/---/g, s/4/----/g, s/5/-----/g, s/6/------/g, s +/7/-------/g, s/8/--------/g; my @x = map {"-" x $_} 0..8; s/([1-8])/$x[$1]/g; 1 while s/([2-8])/-@{[$1-1]}/g; s/1/-/g; s/8/7-/g; s/7/33-/g; s/6/5-/g; s/5/22-/g; s/4/3-/g; s/3/11-/g; s/2/1-/ +g; s/1/-/g;
      s/8/7-/g; s/7/33-/g; s/6/5-/g; s/5/22-/g; s/4/3-/g; s/3/11-/g; s/2/1-/ +g; s/1/-/g;

      This version certainly seems to work, but is it lazy, crazy, peevish, peccant, or...?

      I think it's the version I would choose if I hated the person who would be maintaining my code!

      Update: ++ for the whole reply for diversity and perversity!

        Feel free to replace the semicolons (except the last) with xors for even more perversity.
      s/1/-/g, s/2/--/g, s/3/---/g, s/4/----/g, s/5/-----/g, s/6/------/g, s/7/-------/g, s/8/--------/g;

      This is the exact way I have done it :). When you are lazy you end up with code like this. To be sure: this works.
Re: A silly reg exp question
by TJPride (Pilgrim) on Jan 16, 2012 at 22:23 UTC
    $_ = 'p1r4k/8'; s/(\d+)/'-'x$1/eg; print;

    Output:
    p-r----k/--------