0

I have a javascript value holding a string:

value = "123 / 15 - Value1"

And I'm trying to split on delimiters so that I can have each number and the string value is their own variables.

I tried this:

value = "123 / 15 - Value1"
splitVal = value.split(/[" ".,\/ -]/);
number1 = splitVal[0];
number2 = splitVal[1];
name = splitVal[2];

But when I console log number1,number2 and name I only get '123' in the console, the other 2 are blank.

What am I doing wrong here as far as splitting a string by both a hyphen and a slash, as well as spaces?

4
  • What pattern are you expecting in the string? It would be easy to hardcode a solution for this specific case, but from the context it's not clear how you're trying to parse value in a generic way. Commented Sep 14, 2018 at 14:40
  • @PatrickRoberts the pattern in this case should always be number / number - name with spaces between each value and delimiter but there could be cases where it could be number/number-name Commented Sep 14, 2018 at 14:41
  • [" "] I think you either want " or ` ` (space) here. This regex will match either of the two and uselessly repeats ". Commented Sep 14, 2018 at 14:42
  • Also, since you have a single character class (simplified) [ /] the sequence between the two numbers 123 / 15 matches three times, hence why you get empty results. If you put a quantifier after the square brackers ...]+ you would only get three items after splitting. Commented Sep 14, 2018 at 14:45

9 Answers 9

2

You can use String.prototype.match() and a destructuring assignment with the following RegExp:

const value = '123 / 15 - Value1'
const [, number1, number2, name] = value.match(/(\d+) *\/ *(\d+) *- *(.+)/)

console.log(number1, number2, name)

Sign up to request clarification or add additional context in comments.

Comments

2

The problem is that you split at (space) and / so 123 / 15 becomes:

[
  '123',
  // space
  '',
  // /
  '',
  // space
  '15'
]

If you know how the pattern should look like you might want to use match instead of split:

value = "123 / 15 - Value1"
matchVal = value.match(/^(\d+)\s*\/\s*(\d+)\s*-\s*(.*)$/);
console.dir(matchVal)

With match you can exactly define how the input has to be formatted and which fields of the input you want to extract.

Furthermore it allows name to be something like Value-1 with spaces if this is required, (if this is not allowed you could change the (.*) a more restrictive match):

value = "123 / 15 - Value-1 with spaces"
matchVal = value.match(/^(\d+)\s*\/\s*(\d+)\s*-\s*(.*)$/);
console.dir(matchVal)

Using regex101.com an help you to understand what earch part of the regexp does.

4 Comments

This should have been the accepted answer. It explains the problem and gives a tailored solution with a description of how it works (even though I posted an almost identical RegExp before this :P)
@Patrick Roberts I disagree. Matching the string like so /(\d+)|(\w+)/g with a global flag seems to me a much more reusable solution.
@etarhan depends on the usecase. If you want to have lazy matching then this might be true. But if you want to ensure that the input always matches a certain pattern - what you should always do to keep the code maintainable and prevent that this lazy matching is abused - then you want to test against a more restrictive pattern. That way you will find errors at an early stage. What if the input is illformed because of a bug (or on purpose) and is 10 10 / 10 Name then you might get an error (or an unwanted execution path) at an unexpected place in your code.
@etarhan that kind of attitude is what introduces vulnerabilities into string sanitization libraries. Like t.niese says don't be lazy.
1

You could use match() instead of split():

var value = "123 / 15 - Value1"

var splitVal= value.match(/[a-z0-9]+/gi);

console.log(splitVal)

1 Comment

Yep, perfect! Thank you!
1

With

console.table("123 / 15 - Value1".split(/[" ".,\/ -]/))

you'll find out what really happens is that all values except for indexes 0,3,6 are empty strings

Comments

0

You might have more luck just using a regex to pull out the values instead of trying to use delimiters.

let str = '123 / 15 - Value1';
let reg = /\w+/g;

let res;
let results = [];
while ((res = reg.exec(str)) !== null) {
    results.push(res);
}

if (results.length > 0) {
    console.log('Results = ' + results);
} else {
    console.log('No results.')
}

Comments

0
var value = "123 / 15 - Value1";
var r = value.split(/\s?[\/-]\s?/);
console.log(r);
/*
[ '123', '15', 'Value1' ]
*/

Comments

0

The regex in your code is resulting in ["123", "", "", "15", "", "", "Value1"] .You can see in 1 & 2 index they are empty space. You can slightly modify the regex

var value = "123 / 15 - Value1";

var splitVal = value.split(/[\/-]/),
  number1 = splitVal[0].trim(),
  number2 = splitVal[1],
  name = splitVal[2];

console.log(number1, number2, name)

Comments

0

This will work:

splitVal= value.split(/[" ".,\/ -]+/);

Add a '+' to the end of your regex. It tells the regex there must be at least one occurrence (i.e. no empty strings allowed) which is why your split is returning empty strings (as received from your regex).

Comments

-1

You should remove white spaces before split, like this:

splitVal= value.replace(/ /g,'').split(/[" ".,\/ -]/);

5 Comments

While this would give the correct result for the given case, you still should explain why it won't give the correct result if the spaces are not replaced.
What happens if the input is "123 // 15 - Value1"?
@vlaz according to OP that's not a valid input. Parsing that string does not have to be well-defined.
@PatrickRoberts I was prodding for this answer to be re-thought and/or expanded. The issue isn't that there are spaces - it's how the regex is defined. Solving that is a much better solution. Although explanation for why this solution works is also going to be valuable.
A bigger issue is that this solution would remove spaces from the name before matching it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.