2

I am trying to replace square brackets in a string with an empty string. which means if a string is [SECTION], I want to convert it to SECTION.

I have tried this and it works,

my $sectionName =~ tr/[]//d;
print "$sectionName\n";

However, when I tried to create a general subroutine for replacing strings, it didn't work out. Here's what I tried,

sub strReplace
{
    my $string = shift;
    my $target = shift;     
    my $replacement = shift;

    $target = quotemeta $target;
    $replacement = quotemeta $replacement;

    $string =~ tr/$target/$replacement/d;

    return $string;
}

I am calling the sub like this,

# the string "[SECTION]" below is intended to be replaced by a variable
my $sectionName = strReplace("[SECTION]", "[]", "");
print "$sectionName\n";

However, instead of getting the replaced string, I am still getting the old one, i.e, [SECTION]. What am I doing wrong? (PS: Perl version 5.14.2)

4
  • 3
    It appears tr does not support variables: stackoverflow.com/questions/3382657/… Commented Dec 15, 2013 at 17:28
  • 1
    BTW, I was confused by your subject line. tr does not use regular expressions. The first argument is a set of characters to look for (not a regex), and the second argument is what characters to replace those characters with, if any. When I first set out to answer this question, I hadn't noticed the tr and though you were looking for the substring "[]" in "[SECTION", which of course would not work. Commented Dec 15, 2013 at 17:32
  • 1
    Thanks, never knew tr doesn't support variables (and that it doesn't use regex), went along with s///g construct which works fine. Commented Dec 15, 2013 at 17:35
  • @ysth : Done! I also summarized the two strategies at that link in the body of my answer. Commented Dec 15, 2013 at 18:25

2 Answers 2

4

Perl's tr/// operator does not support variables. You can find various strategies to work around this here: Perl's tr/// is not doing what I want

To summarize, you have two main options:

  • Wrap your tr/// in an eval.
  • Convert your tr/// into a substitution using s///.
Sign up to request clarification or add additional context in comments.

Comments

1

If your main case for strReplace is actually just to remove characters, I'd write a less-general-purpose sub that does that. Otherwise, a s/// conversion that can both remove and replace looks like this:

sub strReplace
{
    my $string = shift;
    my $target = shift;
    my $replacement = shift;

    my %replacement;
    @replacement{ split //, $target } = split //, $replacement;

    $string =~ s{ ([\Q$target\E]) }{ $replacement{$1} // '' }gxe;

    return $string;
}

The substitution repeatedly (because of the /g flag) looks for [\Q$target\E] (a character in a class of any the characters in $target, any special characters automatically escaped if necessary by \Q...\E), and replaces it with the value found by looking in the hash, or just removes it if it wasn't found in the hash.

2 Comments

Thanks for the answer, but you could you explain this syntax, specially the s/// construct you are using? I am not completely sure exactly how it works
Tried to explain, but it's hard without knowing what part(s) you weren't sure about.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.