1

I would like to write a perl regex to replace some pattern to other pattern. The source pattern is lowercase followed by uppercase. The destination pattern is the lowercase followed by dot, space and the uppercase.

Here is an example:

CamelCase

I want to change it to the following:

Camel. Case

Thanks in advance!

kee
  • 10,969
  • 24
  • 107
  • 168

3 Answers3

4

Another solution what accepts utf8 too:

use Modern::Perl;
use utf8;
use Encode qw(encode);

foreach ( qw(CamelCase ČamelČasě ŽaBaČek) ) {
    say Encode::encode('utf8', "$1. $2")
        if( m{(\b\p{Upper}\w*)((?:\p{Lower}\w*\p{Upper}|\p{Upper}\w*\p{Lower})\w*\b)} );
}

produces

Camel. Case
Čamel. Časě
ŽaBa. Ček

based on: https://stackoverflow.com/a/6323679/632407

Community
  • 1
  • 1
clt60
  • 62,119
  • 17
  • 107
  • 194
3

I suggest the following:

$StringToConvert = s/([A-Z][a-z]+)(?=[A-Z])/$1\. /g;

The positive look ahead "(?=[A-Z])" is the key. The only Words that are replaced are those that have another capitalized character in front of it.

Also note the "g" which means to search the string globally. This results in the following:

CamelCase
Camel. Case

as well as

CamelCaseMultiple
Camel. Case. Multiple

And on and on for as many capitalized words there may be in the string.

1

Solution using split and join:

my $str = 'CamelCase';

my @words = split /(?=[A-Z])/, $str;

print join '. ', @words;
Miller
  • 34,962
  • 4
  • 39
  • 60
  • This solution also will change several uppercase letters following each other, like: `theEEUU`. – Birei Mar 14 '14 at 23:07
  • Yes, if the OP wanted to avoid that edge case, the solution would have to revised to `my @words = split /(?<![A-Z])(?=[A-Z])/, $str;`. – Miller Mar 14 '14 at 23:12