How do I split a string into two strings using a space + number delimiter and/or search for the delimiter by counting right to left?

Hello,
I have data entries that look like this:
Column 1 | Column 2
Default | 8
Default 2 | 9
Default 3 | 3
Default 4 | 5
Card 1 | 6
Card 1 2 | 10
Card 1 3 | 3
Card 1 4 | 2
Card 1 5 | 9
Card 1 6 | 3
Card 2 | 2
Card 2 2 | 2
Card 2 3 | 6
Card 2 4 | 8
Card 2 5 | 6
Card 2 6 | 9
I want to be able to split all the column 1 entries into two columns, the base part and the number. The number I'm interested in is ONLY the last number after the last space. The base part is allowed to have a number in it.
The only common thing between all the entries is that they end with [space][number] and number can be between 1 and 10000.
For the entries similar to the (1,1) entry above, I need to get a 0 at the end of that string as well.
I think I can use 'strsplit' or 'regexp' to do this, but I'm not sure how to tell Matlab that I need it to split at the end of the string effectively (have it count in from the right).
Thanks for any assistance you are able to give,
Matt

 Accepted Answer

Not sure what exactly the format of your data is (use valid matlab syntax to construct your examples to avoid ambiguity). Is column 2 relevant here? Also, not sure what "For the entries similar to the (1,1) entry above, I need to get a 0 at the end of that string as well." mean.
To split a char vector 'Card 2 6' or similar into {'Card 2', '6'}:
str = 'Card 2 6';
split = regexp(str, '(.*?) (\d+)$', 'tokens')
This basically creates two tokens, the 2nd token must be preceded by a space, must consist of digits and attached to the end of the input (because of the $. The first token is everything else before the space.

4 Comments

Hi Guillaume,
Thanks for your response. Sorry for the confusion, I'm writing the script on a remote network and can't quickly copy it so my formatting was poor.
Your solution worked well for me, but I identified a small problem with a subset of my data.
It turns out there are four cases I need to identify in my data: the strings can end with a letter, end with a number, end with two numbers, or end with punctuation. Your reponse above works for everything ending in the third case, but creates an issue for anything in the second case.
How would I modify the snippet above to to recognize the difference between a case that ends with a letter-and-number combination versus a case that ends with a letter-number-number combination?
Thanks again,
Matt
Can you show an example of input for each four case, and the desired result for each?
My issue is with a subset of Case 3, but here's a better example of what I need than in my original post. The context for this is that I have to split each entry's part name from its surface number designation.
Case 1 (ends with letter):
'Default' needs to be converted to 'Default 0' then split into 'Default' and '0'.
Case 2 (ends with a number):
'Internal Air 25' needs to be split into 'Internal Air' and '25'.
Case 3 (ends with two numbers):
'Chassis Body - Chassis 1 16' needs to be split into 'Chassis Body - Chassis 1' and '16'.
Case 4 (end with punctuation), this one isn't technically a whole separate case and I have a workaround in place for it:
'Shell - Chassis 3 - 14' needs to be split into 'Shell - Chassis 3' and '14'. The existing snippet you shared splits it into 'Shell - Chassis 3 -' and '14', then I have another line that removes the final space and punctuation.
So the issue I noticed is that sometimes, a part name ends in a number. This case is as follows:
'Chassis Body - Chassis 1' needs to be converted to 'Chassis Body - Chassis 1 0' then split into 'Chassis Body - Chassis 1' and '0'. I'm having trouble figuring out a way to perform the operation for this case without messing up other Case 2 entries.
I'm thinking the easiest way might be to add another case which is "ends with a number but has a hyphen".
Ok, now I understand. Case 1 is significantly different from the other cases that it would be hard to cover it with the same regex. Maybe with a dynamic expression but for clarity and simplicity, it's better to either handle separately or simply do the appending and then handle it as case 2.
There's actually no difference between 2 and 3. You just want the last number split. As for case 4, it's simply a matter of considering punctuation the same as space.
%test cases:
tests = {'Default'; 'Internal Air 25'; 'Chassis Body - Chassis 1 16'; 'Shell - Chassis 3 - 14'};
%append number to case 1:
normalised = regexprep(tests, '\D$', '$0 0'); %replace strings ending with a non-digit by that non-digit followed by a space and 0
%splitting
splitted = regexp(normalised, '(.*?)[- ]+(\d+)$', 'tokens', 'once');
splitted = vertcat(splitted{:})
For the splitting, all the punctuation characters that you want to consider go inside the [] . I put the space and - in there. Add whatever other characters you want to consider. Note that - needs to be first or last in the square brackets (otherwise it has special meaning). Some other characters may also have special meaning (\ and ^ for example), read the regexp doc to check.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2018b

Asked:

on 6 Mar 2019

Commented:

on 11 Mar 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!