Multiple substitution in a complex RE

S

SqlSlinger

I'm trying to convert all occurances of variables of the form

VARIABLE_ONE, VARIABLE_NUMBER_TWO, a_really_long_VARIABLE_name

to the form

VariableOne, VariableNumberTwo, AReallyLongVariableName

Here's my Program:

$_='a_really_long_VARIABLE_name';
s/([A-Za-z])([^_ \t\n]*?)(_([A-Za-z0-9])([^_ \t\n]*?))+/\u$1\L$2\E\u$4\L$5\E/;
print;
__END__

Prints "AReally_long_VARIABLE_name".

Can anyone help?
 
G

Glenn Jackman

SqlSlinger said:
I'm trying to convert all occurances of variables of the form
VARIABLE_ONE, VARIABLE_NUMBER_TWO, a_really_long_VARIABLE_name
to the form
VariableOne, VariableNumberTwo, AReallyLongVariableName


my @vars = qw(VARIABLE_ONE VARIABLE_NUMBER_TWO a_really_long_VARIABLE_name);
my %StudlyCaps;
foreach (@vars) {
my $var = ucfirst lc;
$var =~ s/_(.)/\U$1/g;
$StudlyCaps{$_} = $var;
}
use Data::Dumper;
print Dumper(\%StudlyCaps);
 
U

Uri Guttman

GJ> my @vars = qw(VARIABLE_ONE VARIABLE_NUMBER_TWO
GJ> a_really_long_VARIABLE_name);

GJ> foreach (@vars) {
GJ> my $var = ucfirst lc;
GJ> $var =~ s/_(.)/\U$1/g;
GJ> }

s/_?(.)([^_]*)/\U$1\L$2/g ;

uri
 
J

John W. Krahn

SqlSlinger said:
I'm trying to convert all occurances of variables of the form

VARIABLE_ONE, VARIABLE_NUMBER_TWO, a_really_long_VARIABLE_name

to the form

VariableOne, VariableNumberTwo, AReallyLongVariableName

Here's my Program:

$_='a_really_long_VARIABLE_name';
s/([A-Za-z])([^_ \t\n]*?)(_([A-Za-z0-9])([^_ \t\n]*?))+/\u$1\L$2\E\u$4\L$5\E/;
print;
__END__

Prints "AReally_long_VARIABLE_name".

Can anyone help?


for ( qw/ VARIABLE_ONE VARIABLE_NUMBER_TWO a_really_long_VARIABLE_name / ) {
print;
print join '', map "\u\L$_", split /_/;
}



John
 
S

SqlSlinger

Glenn, Uri, John,

Excellent suggestions all!

Now here's the rest of what I should have told you. I use Perl every
chance I get, but in this case I'm hoping to program a macro in
TextPad to perform this kind of substitution. TextPad REs support
most of the Perl RE features, but not the g (global) modifier and not
loops. This is why I was attempting to get it all done in the s///
statement. If it won't work, of course, I can program a quick perl
script to do it using any of your suggestions, but that's slightly
more inconvenient than the TextPad macro.

For my own info, is there any way to get a repeated outer grouping in
the pattern to replace while referencing (and modifying) the inner
grouping in the replace string?
 
S

SqlSlinger

Uri Guttman said:
GJ> my @vars = qw(VARIABLE_ONE VARIABLE_NUMBER_TWO
GJ> a_really_long_VARIABLE_name);

GJ> foreach (@vars) {
GJ> my $var = ucfirst lc;
GJ> $var =~ s/_(.)/\U$1/g;
GJ> }

s/_?(.)([^_]*)/\U$1\L$2/g ;

uri

Nice and compact, but doesn't isolate only variables containing an
underscore. If run against a source file, would match any word,
right?

Vince
 
F

fifo

Now here's the rest of what I should have told you. I use Perl every
chance I get, but in this case I'm hoping to program a macro in
TextPad to perform this kind of substitution. TextPad REs support
most of the Perl RE features, but not the g (global) modifier and not
loops. This is why I was attempting to get it all done in the s///
statement. If it won't work, of course, I can program a quick perl
script to do it using any of your suggestions, but that's slightly
more inconvenient than the TextPad macro.

If you need a single substitution to work over the entire file, how
about doing something like

s/ ([a-zA-Z0-9])([a-zA-Z0-9]*)(?=_[a-zA-Z0-9_])
| (?<=[a-zA-Z0-9_]_)([a-zA-Z0-9])([a-zA-Z0-9]*)
/\U$1$3\L$2$4/xg
 
U

Uri Guttman

GJ> my @vars = qw(VARIABLE_ONE VARIABLE_NUMBER_TWO
GJ> a_really_long_VARIABLE_name);GJ> foreach (@vars) {
GJ> my $var = ucfirst lc;
GJ> $var =~ s/_(.)/\U$1/g;
GJ> }
s/_?(.)([^_]*)/\U$1\L$2/g ;

uri

S> Nice and compact, but doesn't isolate only variables containing an
S> underscore. If run against a source file, would match any word,
S> right?

probably but that could be fixed with some guard regex stuff. and it
wasn't in the spec which showed a qw list of tokens. you need to code to
what is posted (unless it is obvious the OP is having an XY problem or
way off base).

uri
 
S

SqlSlinger

fifo said:
Now here's the rest of what I should have told you. I use Perl every
chance I get, but in this case I'm hoping to program a macro in
TextPad to perform this kind of substitution. TextPad REs support
most of the Perl RE features, but not the g (global) modifier and not
loops. This is why I was attempting to get it all done in the s///
statement. If it won't work, of course, I can program a quick perl
script to do it using any of your suggestions, but that's slightly
more inconvenient than the TextPad macro.

If you need a single substitution to work over the entire file, how
about doing something like

s/ ([a-zA-Z0-9])([a-zA-Z0-9]*)(?=_[a-zA-Z0-9_])
| (?<=[a-zA-Z0-9_]_)([a-zA-Z0-9])([a-zA-Z0-9]*)
/\U$1$3\L$2$4/xg

Prints A_Really_Long_Variable_Name. Can we lose the underscores? I'm
not familiar with the RE directives you've used to be able to work up
an adjusted version, but I'll look into it. Doesn't seem to affect
text without the underscore, which is nice.

Thanks!
 
F

fifo

fifo said:
If you need a single substitution to work over the entire file, how
about doing something like

s/ ([a-zA-Z0-9])([a-zA-Z0-9]*)(?=_[a-zA-Z0-9_])
| (?<=[a-zA-Z0-9_]_)([a-zA-Z0-9])([a-zA-Z0-9]*)
/\U$1$3\L$2$4/xg

Prints A_Really_Long_Variable_Name. Can we lose the underscores?

Sure, you just need to transpose two characters:

s/ ([a-zA-Z0-9])([a-zA-Z0-9]*)(?=_[a-zA-Z0-9_])
| (?<=[a-zA-Z0-9_])_([a-zA-Z0-9])([a-zA-Z0-9]*)
/\U$1$3\L$2$4/xg

Now you should get AReallyLongVariableName.
 
S

SqlSlinger

Fifo,
Sure, you just need to transpose two characters:

s/ ([a-zA-Z0-9])([a-zA-Z0-9]*)(?=_[a-zA-Z0-9_])
| (?<=[a-zA-Z0-9_])_([a-zA-Z0-9])([a-zA-Z0-9]*)
/\U$1$3\L$2$4/xg

Now you should get AReallyLongVariableName.

I did indeed! I'm been staring at the expression and trying to make
sense of it. I've looked up ?= and ?<= directives, and they're
starting to crack my brain's permafrost, but I'm still confused as to
why this works. On first glance, the replacement expression would
appear to give all upper case followed by all lower case. I would
have expected the replacement expression to look like

\u$1\L$2\u$3\L$4

Can you explain this a bit further? I'm hoping to make greater use of
the directives once I understand this example...
 
F

fifo

s/ ([a-zA-Z0-9])([a-zA-Z0-9]*)(?=_[a-zA-Z0-9_])
| (?<=[a-zA-Z0-9_])_([a-zA-Z0-9])([a-zA-Z0-9]*)
/\U$1$3\L$2$4/xg

Now you should get AReallyLongVariableName.

I did indeed! I'm been staring at the expression and trying to make
sense of it. I've looked up ?= and ?<= directives, and they're
starting to crack my brain's permafrost, but I'm still confused as to
why this works. On first glance, the replacement expression would
appear to give all upper case followed by all lower case. I would
have expected the replacement expression to look like

\u$1\L$2\u$3\L$4

Can you explain this a bit further? I'm hoping to make greater use of
the directives once I understand this example...

The regex has two alternate parts: the first part matches a sequence of
alphnum characters [a-zA-Z0-9] followed by an underscore and another
alphnum character; the second part matches a sequence of alphnum
characters that are preceeded by an alphnum character and an underscore.
In the first case, $1 is set to the first character and $2 to the rest;
in the second case $3 is set to the first character and $4 to the rest
(and the underscore is discarded). Then we upcase the first letter
"$1$3" and downcase the rest "$2$4".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top