A Way to Automate “Regular” Renaming
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.
Published with MATLAB® 7.6