denn4617
denn4617

Reputation: 383

JavaScript Regex split at first letter?

Since many cases using Regex, differs from case to case, depending on what format your string is in, I'm having a hard time finding a solution to my problem.

I have an array containing strings in the format, as an example:

"XX:XX - XX:XX Algorithm and Data Structures"

Where "XX:XX - XX:XX" is timespan for a lecture, and X being a number.

I'm new to Regex and trying to split the string at the first letter occurring, like so:

let str = "08:15 - 12:50 Algorithm and Data Structures";
let re = //Some regex expression
let result = str.split(re); // Output: ["08:15 - 12:50", "Algorithm and Data Structures"]

I'm thinking it should be something like /[a-Z]/ but I'm not sure at all...

Thanks in advance!

Upvotes: 1

Views: 307

Answers (5)

The fourth bird
The fourth bird

Reputation: 163362

For that format, you might also use 2 capture groups instead of using split.

^(\d{1,2}:\d{1,2}\s*-\s*\d{1,2}:\d{1,2})\s+([A-Za-z].*)

The pattern matches:

  • ^ Start of string
  • (\d{1,2}:\d{1,2}\s*-\s*\d{1,2}:\d{1,2}) Capture group 1, match a timespan like pattern
  • \s+ Match 1+ whitspac chars
  • ([A-Za-z].*) Capture group 2, start with a char A-Za-z and match the rest of the line.

Regex demo

let str = "08:15 - 12:50 Algorithm and Data Structures";
let regex = /^(\d{1,2}:\d{1,2}\s*-\s*\d{1,2}:\d{1,2})\s+([A-Za-z].*)/;
let [, ...groups] = str.match(regex);
console.log(groups);

Another option using split might be asserting not any chars a-zA-Z to the left from the start of the string using a lookbehind (see this link for the support), match 1+ whitespace chars and asserting a char a-zA-Z to the right.

(?<=^[^a-zA-Z]+)\s+(?=[A-Za-z])

Regex demo

let str = "08:15 - 12:50 Algorithm and Data Structures";
let regex = /(?<=^[^a-zA-Z]+)\s+(?=[A-Za-z])/;
console.log(str.split(regex))

Upvotes: 0

dale landry
dale landry

Reputation: 8610

I know you asked about regex in particular, but here is a way to this without regex...

Provided your time span is always at the beginning of your string and will always be formatted with white space between the numbers as XX:XX - XX:XX. You could use a function that splits the string at the white space and reconstructs the first three indexed strings into one chunk, the time span, and the last remaining strings into a second chunk, the lecture title. Then return the two chunks as an array.

let str = "08:15 - 12:50 Algorithm and Data Structures";

const splitString = (str) => {
  // split the string at the white spaces
  const strings = str.split(' ')
  // define variables
  let lecture = '',
    timespan = '';
  // loop over the strings
  strings.forEach((str, i) => {
    // structure the timespan
    timespan = `${strings[0]} ${strings[1]} ${strings[2]}`;
    // conditional to get the remaining strings and concatenate them into a new string
    i > 2 && i < strings.length?lecture += `${str} `: '';
  })
  // place them into an array and remove white space from end of second string
  return [timespan, lecture.trimEnd()]
}


console.log(splitString(str))

Upvotes: 0

Hassen Ch.
Hassen Ch.

Reputation: 1751

If you have a fixed length of the string where the time is, you can use this regex for example

(^.{0,13})(.*)

Check this here https://regex101.com/r/ANMHy5/1

Upvotes: 0

dave
dave

Reputation: 64657

console.log(
    "08:15 - 12:50 Algorithm and Data Structures".split(/ ([A-Za-z].*)/).filter(Boolean)
)

or, if it's really always XX:XX - XX:XX, easier to just do:

const splitTimeAndCourse = (input) => {
    return [
        input.slice(0, "XX:XX - XX:XX".length),
        input.slice("XX:XX - XX:XX".length + 1)
    ]
    
}

console.log(splitTimeAndCourse("08:15 - 12:50 Algorithm and Data Structures"))

Upvotes: 1

DemiPixel
DemiPixel

Reputation: 1881

The easiest way is probably to "mark" where you want to split and then split:

const str = '12 34 abcde 45 abcde'.replace(/^([^a-z]+)([a-z])/i, '$1,$2');
// '12 34 ,abcde 45 abcde'
str.split(',')
// [ '12 34 ', 'abcde 45 abcde' ]

This finds the place where the string starts, has a bunch of non a-z characters, then has an a-z characters, and puts a comma right in-between. Then you split by the comma.

You can also split directly with a positive look ahead but it might make the regex a bit less readable.

Upvotes: 1

Related Questions