6

I have a regular expression that replaces all special characters with % (for database searching with LIKE). It looks like this:

$string =~ s/[^ a-zA-Z0-9]/%/g;

However I don't know how to change that expression to replace all desired special characters EXCEPT for the first one in a string. So if my string look like

"&Hi I'm smart(yeah right...)"

it would be

"&Hi I%m smart%yeah right%%%%"

(Right now the first '&' is also replaced).

Can any one help?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
srd.pl
  • 571
  • 10
  • 22

3 Answers3

3

You could use a look-behind assertion requiring at least one character:

s/(?<=.)[^ a-zA-Z0-9]/%/g;
FMc
  • 41,963
  • 13
  • 79
  • 132
  • 1
    That only works if the first character is a special character. It does not work to change all but the first such special character in the general case. – tchrist Apr 21 '11 at 14:44
3

This changes all but the first instance of the match target into a percent symbol:

{
    my $count = 0;
    $string =~ s{([^ a-zA-Z0-9])}{$count++ ? "%" : $1}ge;
}
tchrist
  • 78,834
  • 30
  • 123
  • 180
2
substr($string, 1) =~ s/[^ a-zA-Z0-9]/%/g;

Update: The above only works if the special character is the first character of the string. The following works no matter where it's located:

my $re = qr/[^ a-zA-Z0-9]/;
my @parts = split(/($re)/, $string, 2);
$parts[2] =~ s/$re/%/g if @parts == 3;
$string = join('', @parts);
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • But what if the first “special character” is not the first character? – tchrist Apr 21 '11 at 14:44
  • @tchrist, then that would be a different question with a different answer. – ikegami Apr 21 '11 at 15:14
  • @tchrist, or maybe not. After re-reading a few more times, I'm with you. – ikegami Apr 21 '11 at 15:16
  • I think you could possibly do it with [a nested regex](http://stackoverflow.com/questions/5678422/regex-matching-irreducible-fraction/5695425#5695425), but I think the `s///e` solution that counts is cleaner to look at than any nested thing could be. – tchrist Apr 21 '11 at 15:32
  • /e is definitely cleaner, @tchrist. Both of my solution fall into the "here's something you hadn't thought of you might one day find useful". Besides, you already gave the /e solution. – ikegami Apr 21 '11 at 15:38