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

i have a many text pages and i want to replace all the words beginning with tbgl_ such as tbgl_translate with another one deleting the prefix tbgl_ and adding a suffix _gl to the end of the word ie like this:
tbgl_translate ---> translate_gl
tbgl_vertex ---> vertex_gl
and so on ... for other words

the problem is that sometimes the words can have "(" such as tbgl_translate(...)
a friend advice me to request a regex from the monks in this forum, it seems to me impossible task, i know a little about regexes, i am visiting your holy temple and thanks in advance for any help.

Replies are listed 'Best First'.
Re: regex replace problem
by JavaFan (Canon) on Nov 18, 2010 at 13:32 UTC
    the problem is that sometimes the words can have "(" such as tbgl_translate(...)
    Does that mean that "tbgl_translate(" needs to be turned into "translate(_gl"? If not, that is, if the '(' is totally irrelevant, what's the problem here? In that case,
    s/tbgl_(\pL+)/${1}_gl/g;
    ought to do it.
      thank you Fisher and JavaFan ,i mean such as tbgl_translate(...) ---> translate_gl(...)
      your code works with many words,sample of that converted words inside htm files such as:
      href="SetMaterialSpecular_gl.htm">SetMaterialSpecular_gl
      CLASS="f_Code_Keyword">SetMaterialSpecular_gl
      but i have found that some words does not converted, it is in htm files not text , the not converted words like this inside the htm files:
      CLASS="f_Code_Keyword">TBGL_SetMaterialDiffuse( hMaterial, R, G, B )
      i want to replace TBGL_SetMaterialDiffuse(...) by
      SetMaterialDiffuse_gl(...)
      and so on for other words
      my code until now using javaFan regex:
      $file = "TBGL_SetMaterialDiffuse.htm"; open(FILE, $file) || die $!; $txt = do { local $/; <FILE> }; close FILE; $txt =~ s/tbgl_(\pL+)/${1}_gl/g; open FILE, ">output.htm" or die $!; print FILE $txt; close FILE;
      thanks
        See, that's what you get from not specifying your problem, and just giving an example that doesn't cover all the cases. You got an answer to your described problem, and now you have to come back with "well, really, the problem I described wasn't really the problem I'm trying to solve. In fact, this is the problem....".

        Use /i. For details, RTFM.

        add case-insensitive option.
        s/tbgl_([^ \t(_]+)/$1_gl/gi;
        and again, perldoc perlretut
Re: regex replace problem
by fisher (Priest) on Nov 18, 2010 at 13:25 UTC
    s/tbgl_([^ \t(_]+)/$1_gl/;
    please read the `perldoc perlretut`.
Re: regex replace problem
by AnomalousMonk (Archbishop) on Nov 18, 2010 at 22:54 UTC

    It's very useful to 'factor' regexes as one would factor subroutines. The relationships of the parts to each other and to the whole are clarified, and it becomes easier to change a part when necessary. This clarity and ease of maintenance can be important for complex regexes (or for simple regexes when you're trying to debug one at 3 AM!).

    >perl -wMstrict -le "my $prefix = qr{ (?i) \b tbgl_ }xms; my $word = qr{ \w+ }xms; my $suffix = '_gl'; ;; print '--- output ---'; for my $pw (@ARGV) { (my $ws = $pw) =~ s{ $prefix ($word) }{$1$suffix}xmsg; print qq{'$pw' -> '$ws'}; } " "tbgl_foo xxx %$# tbgl_bar()" "TBGL_foo tBgL_bar" "tbgl tbglfoo tbgl_" "tbgl_%$# Xtbgl_foo" --- output --- 'tbgl_foo xxx %$# tbgl_bar()' -> 'foo_gl xxx %$# bar_gl()' 'TBGL_foo tBgL_bar' -> 'foo_gl bar_gl' 'tbgl tbglfoo tbgl_' -> 'tbgl tbglfoo tbgl_' 'tbgl_%$# Xtbgl_foo' -> 'tbgl_%$# Xtbgl_foo'

    In the example above, it was only necessary to change the definition of  $prefix from
        my $prefix = qr{ \b tbgl_ }xms;
    to
        my $prefix = qr{ (?i) \b tbgl_ }xms;
    when somebody said "Oh, by the way, the prefix pattern is supposed to be case insensitive."

    One could use the /i regex modifier (see Modifiers in perlre) instead of the  (?i) extended pattern (see Extended Patterns in perlre) to make  $prefix case insensitive, but the latter is less easy to overlook.

Re: regex replace problem
by Anonymous Monk on Nov 18, 2010 at 18:28 UTC
    i have collected the various situations in the following text , sorry for the confusion, :
    title>TBGL_SetMaterialDiffuse</title
    Heading1">TBGL_SetMaterialDiffuse</span
    href="tbgl_SetMaterialDiffuse.htm">
    ">tbgl_SetMaterialDiffuse</
    f_Code_Keyword">TBGL_DeleteMaterial</span

    the target is to convert TBGL_SetMaterialDiffuse to SetMaterialDiffuse_gl
    the same is for other words wich prefixed by TBGL_ whether it is small or capital letters.
    the text is from a help file of an opengl module in which the author make a second syntax for the persons who does not like the prefixes, but he keeps the help file as the original, so since i want to use the second version, i must convert the help file myself whether manualy or other method
    than you

      One of the following two options should work for all cases you listed. I had to use two because I don't know what your desired result is for the 'href' line.

      OPTION 1
      If you want your example
      "href="tbgl_SetMaterialDiffuse.htm">
      to look like
      "href="SetMaterialDiffuse.htm_gl">
      you should use the following:

      $tmp =~s/TBGL_([a-z]+(\.[a-z]+)?)/$1_gl/i;

      OPTION 2
      If you want that example to look like
      "href="SetMaterialDiffuse_gl.htm">
      use this:
      $tmp =~s/TBGL_([a-z]+)/$1_gl/i;

      I hope this helps :)

      Here is a quick script to test the cases

      #!/usr/bin/perl use strict; my @lines = ( 'title>TBGL_SetMaterialDiffuse</title', 'Heading1">TBGL_SetMaterialDiffuse</span', 'href="tbgl_SetMaterialDiffuse.htm">', '">tbgl_SetMaterialDiffuse</', 'f_Code_Keyword">TBGL_DeleteMaterial</span' ); foreach my $tmp (@lines) { print "$tmp\n"; #$tmp =~s/TBGL_([a-z]+(\.[a-z]+)?)/$1_gl/i; #case 1 $tmp =~s/TBGL_([a-z]+)/$1_gl/i; #case 2 print "$tmp\n\n"; }
        thank you wallisds , your second regex works well ,
        i have applied it to the htm file and replaced the words as expected
        thanks
Re: regex replace problem
by Anonymous Monk on Nov 18, 2010 at 13:22 UTC
    it doesn't need any kind of regex
    s/tbgl_translate/translate_gl/