2

i want to split string between 2 patterns so that i will get correct item

i want to split below string between

_333/4444.json or _(3 or 4 numbers).json

Below is my pattern:

"test_halloween Party 10 AM - 12:30 PM party_560.json"

"Kaulampur 1110 reva_2018  RR_999 Roadrover_4987.json"

split based on :

_560.json


_4987.json

Final Output:

1) 560

2) 4987

here is what i have tried:

var str1 = "test_halloween Party 10 AM - 12:30 PM party_560.json";
var str2 = "Kaulampur 1110 reva_2018  RR_999 Roadrover_4987.json";


var res1 = str1.split(/_./)[0];

var res2 = str2.split(/_./)[0];

console.log(res1);

console.log(res2);

Note: a single pattern should give me both results

4 Answers 4

3

Try a regular expression.

Here's a good primer on how they work: https://www.codepicky.com/regex/

/_(\d{3,4})\.json$/

What is happening with this pattern?

  1. The beginning and ending / are simply bookends defining a pattern
  2. The _ literal will match the underscore that precedes the digits
  3. (\d{3,4}) defines a "capture group" that matches exactly 3 or 4 consecutive numeric digits. This is handy because it lets us extract the digits you want separately from the overall pattern.
  4. \.json$ matches the string .json (you have to escape the period with a slash because it is a special regex character) and the $ enforces it being at the end of the string

Example:

let result1 = "test_halloween Party 10 AM - 12:30 PM party_560.json".match(/_(\d{3,4})\.json$/);
// result1[1] === 560

let result2 = "Kaulampur 1110 reva_2018  RR_999 Roadrover_4987.json".match(/_(\d{3,4})\.json$/);
// result2[1] === 4987

let result3 = "this string will not match".match(/_(\d{3,4})\.json$/);
// result === null

Regular expressions are extremely versatile, precise, and fast. Take a look at this benchmark comparing it to a string index-finding alternative: http://jsben.ch/lbfUt

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

1 Comment

You know, I wrote a hand-coded min-DFA for this and unsurprisingly native regex compilation was faster (avoiding JIT overhead) by ~300ms. Actually, my original solution was faster than the hand-coded DFA. Browsers certainly optimize the hell out of the standard js lib---kudos for the benchmarks +1!
3

I'd solve it like this (slower than pre-compiled regex):

function myFunc(s) {
    let i = s.lastIndexOf("_");
    let j = s.indexOf(".", i);
    return s.substring(i+1, j);
}

console.log(
    myFunc("test_halloween Party 10 AM - 12:30 PM party_560.json"),
    myFunc("Kaulampur 1110 reva_2018  RR_999 Roadrover_4987.json")
);

Anyone interested in the hand-coded DFA mentioned in comments:

function myFunc(s) {
  const MAX = 10;
  t = s.substr(-MAX);
  for (let i=0; i<MAX; i++) {
    let z = "";
    if (t[i] === "_") {
      i++;
      if (isd( t[i] )) {
        z += t[i];
        i++;
        if (isd( t[i] )) {
          z += t[i];
          i++;
          if (isd( t[i] )) {
            z += t[i];
            i++;
            const IS_DOT = 1;
            const IS_DIGIT = 2;
            let x = (t[i] === ".")
              ? IS_DOT 
              : (isd(t[i]))
                ? IS_DIGIT
                : 0;
            OUT:
            while (true) {
              switch (x) {
              case IS_DOT:
                i++;
                if (t.substring(i) === "json") {
                  return z;
                }
                break;
              case IS_DIGIT:
                z += t[i];
                i++;
                x = IS_DOT;
                break;
              default:
                break OUT;
              }
            }
          }
        }
      }
    }
  }
  return null;
}

function isd(c) {
  let x = c.charAt(0);
  return (x >= "0" && x <= "9");
}

console.log(
    [
        "_asnothusntaoeu_2405.json",
        "_asnothusntaoeu_105.json",
        "_asnothusntaoeu_5.json",
        "_asnothusntaoeu.json",
        "_asnothusntaoeu_5json",
        "_asnothusntaoeu_5.jso",
        "_asnothusntaoeu_105.json"
    ].map(s => myFunc(s))
);

1 Comment

Not a bad approach. However it's not actually "much more performant". RegEx uses a native parsing engine that is extremely fast. My RegEx solution posted here is actually about 20% faster than this (in Chrome 70). Take a look at this benchmark: jsben.ch/lbfUt :)
0

try this var res1 = /([0-9]+)\.json$/.exec(str1)[1];

Comments

0

This seems like a textbook case of when you'd just want to use a Regular Expression. Something like:

// Select all things of the form "_<numbers>.json" from 
// the string, and parse out <numbers> as a match.
var MyRegEx = /_(\d+)\.json/i;

var str1 = "test_halloween Party 10 AM - 12:30 PM party_560.json";
var res1 = MyRegEx.exec(str1)[1];

var str2 = "Kaulampur 1110 reva_2018  RR_999 Roadrover_4987.json";
var res2 = MyRegEx.exec(str2)[1];

console.log(res1);    
console.log(res2);

That should do the trick.

Comments

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.