Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

regex replace a string

by OldChamp (Acolyte)
on Nov 03, 2017 at 23:37 UTC ( #1202729=perlquestion: print w/replies, xml ) Need Help??

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

In a text file there are constant string1, for example Event "?" followed by some text and then a string2, which is spacebspace- or spacewspace-.

I want to replace string1 with Event "Black to move" or Event "White to move" dependant on srting2.

Replies are listed 'Best First'.
Re: regex replace a string
by 1nickt (Canon) on Nov 03, 2017 at 23:44 UTC

    Hi, welcome, please show:

    1. sample input (in <code></code> tags)
    2. expected output from that input (in <code></code> tags)
    3. code you have tried (in <code></code> tags)
    4. how it fails (in <code></code> tags if it's an error message)

    see PerlMonks FAQ: Posting on PerlMonks

    The way forward always starts with a minimal test.
Re: regex replace a string
by AnomalousMonk (Bishop) on Nov 04, 2017 at 03:57 UTC

    Here's a guess at something that might be a little like what you think you may need (requires Perl version 5.10 or greater):

    c:\@Work\Perl\monks\OldChamp>perl -wMstrict -le "use 5.010; ;; my %replacement = ( 'foo' => 'Black to move', 'bar' => 'White to move', 'zot' => 'Green to quit', ); ;; my ($string2) = map qr{ \b (?: $_) \b }xms, join ' | ', map quotemeta, reverse sort keys %replacement ; print 'regex: ', $string2; ;; my $s = 'Event ? followed by some text and then foo'; print qq{before: '$s'}; ;; $s =~ s{ Event \s+ \K [?] (?= .*? ($string2)) }{$replacement{$1}}xms; print qq{after: '$s'}; " regex: (?msx-i: \b (?: zot | foo | bar) \b ) before: 'Event ? followed by some text and then foo' after: 'Event Black to move followed by some text and then foo'
    Please see perlre, perlretut, and perlrequick.


    ... a string2, which is spacebspace- or spacewspace-.
    I don't understand what "spacebspace-" and "spacewspace-" are supposed to be. Please clarify, perhaps with an example string like
        'Event ? followed by some text and then spacebspace-'
    with  spacebspace- replaced by a concrete example of whatever it might be.

    Give a man a fish:  <%-{-{-{-<

      The textfile contains text like this
      [Event "?"] [Result "*"] [SetUp "1"] [FEN "4b3/pq2p1k1/1p1pP2R/1P1P2K1/2rp4/8/P5Q1/8 w - - 0 50"] [PlyCount "0"] * [Event "?"] [Round "39"] [Result "*"] [SetUp "1"] [FEN "5rk1/5p1p/3q2p1/1Rp1n3/P3P3/3Pb1pP/2Q3B1/3R3K b - - 0 1"]

      I want to change [Event "?"] to [Event "Black to move"] if in the line [FEN .... ] I find a space, then b followed by another space

      and to change it to [Event "White to move"] if in the line [FEN .... ] I find a space, then w followed by another space

      I have tried to use lookahead, but as have not programmed anything in Perl for quite a while with no success.

      Sorry for beeing unclear

      2017-11-07 Athanasius added code tags

        I don't have time to post a tested solution to your post sharpening the confusing specifications of the OPed problem. Whenever I post untested stuff, there's usually a huge bug right in the middle of it, but anyway...

        The solution I posted here can fairly easily be adapted to your expanded, clarified specifications if you can load the entire file into memory at once, i.e., if the file is smaller than, say, a couple hundred MB (assuming your running on a bargain-basement laptop). I'm assuming you know how to "slurp" a file in this way and that it's been slurped into the  $s scalar. Then, change the  %replacement hash to

        my %replacement = ( 'b' => 'Black to move', 'w' => 'White to move', );
        and change the  s///g substitution to
        $s =~ s{ Event \s+ " \K [?] (?= " .*? FEN [^\n]* \s+ ($string2) \s+ -) } {$replacement{$1}}xmsg;
        This assumes that:
        • There can be any number, including zero, of lines between the Event and FEN lines, or they can be on the same line;
        • FEN is always on the same line as the b/w business (update: but see Update below);
        • Event-FEN-b/w sequences are never nested or interleaved;
        • Event-FEN-b/w all match case-sensitively.
        After the  s///g substitution, write the modified  $s scalar out to a file.

        If you know for sure that the mapping in the  %replacement hash will never change, you can get rid of the code building the  $string2 regex based on the hash and just define the regex as
            my $string2 = qr{ \b (?: b | w) \b }xms;
        (although I hope you will give it a better name).

        Again, this untested code still needs Perl version 5.10+ regex extensions (although it could fairly easily be adapted to an earlier version), and it's untested.

        Update: On second thought, it seems to me that there's a possible problem with the  \s+ ($string2) \s+ sub-pattern of the
            Event \s+ " \K [?] (?= " .*? FEN [^\n]* \s+ ($string2) \s+ -)
        regex that I've suggested for the  s/// match. The  \s class includes newline, so  \s+ could match a wild and crazy string like  "\t \n\t\n\n  \t" that is obviously not all one line as one of the assumptions stated above would have it. It may not make any practical difference, but I think I would rather use something like  [ \t]+ in place of  \s+ in the problematic sub-pattern, making it  [ \t]+ ($string2) [ \t]+ instead. Of course, the all-one-line assumption referred to may not actually be pertinent; in that case, no problem.

        Give a man a fish:  <%-{-{-{-<

        Yes, still unclear. Please read Writeup Formatting Tips to understand how to wrap sample data in either <code>...</code> or <pre>...</pre> tags. What you posted this time is rendered without the constraints of those sorts of tags, and thus some of the specifics we're looking to understand are lost. Why is all your text showing as links?


Re: regex replace a string
by AnomalousMonk (Bishop) on Nov 04, 2017 at 03:36 UTC

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1202729]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2022-10-06 01:43 GMT
Find Nodes?
    Voting Booth?
    My preferred way to holiday/vacation is:

    Results (26 votes). Check out past polls.