Loren on the Art of MATLAB

Turn ideas into MATLAB

A Way to Automate “Regular” Renaming 17

Posted by Loren Shure,

Recently someone at MathWorks asked me how he could automate the renaming of a bunch of M-files containing underscores ('_') in the names with derived names that removed the underscores and used camelCasing instead. You may have similar name manipulation operations you need to perform.

 

Contents

My First Attempt

Of course I resorted to using MATLAB for the task, despite other options. I chose the following requirements.

  • Don't worry about leading _
  • Don't worry about cell arrays of strings or string matrices (vectors only need apply)
  • Do worry about multiple consecutive _
  • Do worry about trailing _

Some Sample Names

I first create a list of some sample names so I have a test suite to try out.

names = {'foo_bar','foo_bar_','foo__bar', ...
    'foo_bar__', 'foo_3','foo_3_','foo_3a', ...
    'foo_bar____baz___234___'};
allnames = names'
allnames = 
    'foo_bar'
    'foo_bar_'
    'foo__bar'
    'foo_bar__'
    'foo_3'
    'foo_3_'
    'foo_3a'
    'foo_bar____baz___234___'

My Solution

Let's first try out my solution on these.

for name = names
    disp(camelCase(name{1}));
end
fooBar
fooBar
fooBar
fooBar
foo3
foo3
foo3a
fooBarBaz234

And now let's look at the code.

type camelCase
function y = camelCase(x)
%camelCase Convert name with underscores to camelCase.

% find the underscores 
indall = find(x=='_');
% figure out where consecutive _ are 
% and remove all but the last 
consec = diff(indall)==1;
ind = indall;
ind(consec) = [];

y = x;
y(min(ind+1,end)) = upper(y(min(ind+1,end)));
y(indall) = '';

I first find all the underscores. Then I look for consecutive ones since I really only want the last one in each sequence,
since it's the following character that I want to turn into upper case. That is, if a following character exists! So I have to check for that too. I then have an array of indices to upper case (though I
allow myself to uppercase _ at the end if it's the last character so I don't have to lengthen my input array; upper('_') is the same as '_'). Now, I go back and use the original indices pointing to all the instances of '_' and remove them. Voila!

History Lesson

And then I got some pangs, because I am well aware that MATLAB supports regular expressions. First some history. Did you know that Stephen Kleene, an American mathematician, was the inventor of regular expressions? He has also been credited with developing a very approachable
proof to Gödel's incompleteness theorems. And some punster then said, "Kleeneliness is next to Gödeliness".

Using regexprep

My friend, colleague, and regexp guru, Jason Breslau gave me the regexprep solution to the problem. Using the same names as before, I next show you Jason's magical 1-line expression, producing the
same output as my M-file above.

for name = names
    disp(regexprep(name{1}, '_+(\w?)', '${upper($1)}'));
end
fooBar
fooBar
fooBar
fooBar
foo3
foo3
foo3a
fooBarBaz234

Conclusions

My code is still easier for me to understand, and I conclude from that that I should spend some time trying to master regular expressions.
In addition, the regular expression code requires no temporary variables, some of which could be large if the input string
is long enough. It also occurs to me that regular expressions are a topic worthy of students learning well in college. What
do you think? Let me know here.

Get the MATLAB code

Published with MATLAB® 7.6

5 views (last 30 days)  | |

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.