9

I want to remove hyphens (-), slashes (/) and white space () from a string name(i) so that I can use it as a structure field name.

This is the ugly way I am currently doing it using the function strrep:

cell2mat(strrep(strrep(strrep(name(i), '-',''),'/',''),' ', ''))

I have also tried other variations, such as:

strrep(name(i),{'-','/'},{'',''});
strrep(name(i),['-','/'],['','']);

What is a more efficient way of doing this?

gnovice
  • 125,304
  • 15
  • 256
  • 359
Elpezmuerto
  • 5,391
  • 20
  • 65
  • 79

4 Answers4

10

Note: I'm guessing your variable name is a cell array of strings, in which case you will want to use {} (i.e. content indexing) instead of () (i.e. cell indexing) to get the strings from it...

As with many problems in MATLAB, there are a number of different ways you can solve this...


Option 1: You could use the function REGEXPREP. The following removes hyphens, forward slashes, and whitespace:

newName = regexprep(name{i},'[-/\s]','');

The benefit here is that the \s will match and replace all whitespace characters, which includes a normal space (ASCII code 32) as well as tabs, newlines, etc..

If you want to be safe and remove every character that is not valid in a MATLAB variable/field name, you can simplify the above to this:

newName = regexprep(name{i},'\W','');


Option 2: If you don't need to worry about removing anything other than the 3 characters you listed, you could use the function ISMEMBER like so:

newName = name{i};
newName(ismember(newName,'-/ ')) = [];


Option 3: If you want to just keep everything that is an alphanumeric character and dump the rest (hyphens, whitespace, underscores, etc.), you could use the function ISSTRPROP:

newName = name{i};
newName = newName(isstrprop(newName,'alphanum'));
gnovice
  • 125,304
  • 15
  • 256
  • 359
  • 2
    Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. :) Seriously -nice. – Marc Nov 17 '10 at 13:55
  • I was already using regexp and just wanted to know what are legal characters, so no new problems for me... ;-) – sage Aug 12 '13 at 20:13
6

The easiest way is to use the built in function genvarname. It will make the name look uglier, but its guaranteed to be a valid name AND it will retain you original uniqueness.

If you just want to remove specific characters, you can use regexprep:

regexprep('foo- /foo- /foo', '[- \/]', '')
Rich C
  • 3,164
  • 6
  • 26
  • 37
  • 2
    +1: `genvarname` is the correct solution to the overall problem. Regular expressions, however, are a heavyweight solution to a simple problem. – Oliver Charlesworth Nov 16 '10 at 18:49
  • GENVARNAME is interesting, but it only removes the spaces. It replaces the other characters by their hex representations, which makes for a hideous name to use for a structure field. – gnovice Nov 16 '10 at 19:02
  • 1
    As I said above, it will make the name look ugly, but it guarantees your name is valid and retains your original uniqueness. If you want to manually replace / delete chars, you have to be careful to 1) remove all invalid chars 2) not destroy your original uniqueness. – Rich C Nov 16 '10 at 22:16
  • hang: The "not destroying uniqueness" point is a good one, although it would be kind of odd if the hyphens, slashes, and such were the *only* things making the strings unique. – gnovice Nov 17 '10 at 19:35
0

Strings are just arrays, so you could do something like:

name(name == '-' | name == '/' | name = ' ') = [];

With respect to your overall goal, there are many more characters that aren't valid in a struct name. You're bet off defining a set of allowable characters, and eliminating everything that isn't in that set.

e.g.:

function i = isAllowed(str)

i = (str >= '0' & str <= '9') ...
  | (str >= 'a' & str <= 'z') ...
  | (str >= 'A' & str <= 'Z');


...

name(~isAllowed(name)) = [];
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
0

Here's another solution:

name = 'some/path/file-name ext';    %# sample string
blacklist = {'-' '/' ' '};           %# list of character not allowed

idx = cell2mat( cellfun(@(c)strfind(name,c), blacklist, 'UniformOutput',false) );
name(idx) = '_';                    %# you can remove/replace those locations

>> name
 name =
 some_path_file_name_ext
Amro
  • 123,847
  • 25
  • 243
  • 454