srb7
srb7

Reputation: 337

Return first occurrence of time regex before specific string within larger string

I've read online how to find the first occurrence of a string after a string, but I'm trying to find it before a string.

I've only recently started using regex so this may be a very simple question.

Example text:

03:47:06 This is line 1
03:47:07 This is line 2
03:47:08 This is line 3
03:47:09 This is line 4
This is line 5
03:47:10 This is line 6
03:47:11 This is line 7
This is line 8

I want to be able to have a variable return the first time stamp that comes before a specific string.

So for example, the time stamp of line 4, I need a variable to return 03:47:09

I have the regex:

/\d\d:\d\d:\d\d/

I could probably figure out how to do it by looping through every line looking for the regex until the text "line 4" appears, but because there will be a LOT of lines I figured there must be an easier way?

Upvotes: 0

Views: 64

Answers (3)

Andrelec1
Andrelec1

Reputation: 382

use regex like this :

([\d+|:]+) This is line 4

https://regex101.com/r/39qC3F/2

Edit with only 'line 4':

([\d+|:]+)[\w ]*line 4[\w ]*

https://regex101.com/r/39qC3F/3

Exemple of use :

const pattern = 'line 4';
const regex = new RegExp(`([\\d+|:]+)[\\w ]*${pattern}[\\w ]*`, 'gm');
const str = `03:47:06 This is line 1
03:47:07 This is line 2
03:47:08 This is line 3
03:47:09 This is line 4
This is line 5
03:47:10 This is line 6
03:47:11 This is line 7
This is line 8`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Upvotes: 0

James Wilkins
James Wilkins

Reputation: 7357

Other answers are good, but if you need to match only at the beginning, then use this:

var string_of_text = `03:47:06 This is line 1
03:47:07 This is line 2
03:47:08 This is line 3
03:47:09 This is line 4
This is line 5
03:47:10 This is line 6
03:47:11 This is line 7
This is line 8 03:33:12`;
var start_timestamp = string_of_text.match(/^([\:\d]){8}/gm)

["03:47:06", "03:47:07", "03:47:08", "03:47:09", "03:47:10", "03:47:11"]

That said, based on your comments, I'm guessing that you are trying to match up the returned times with the lines ... ? In that case you should split the lines first:

string_of_text.split('\n').map(v=>(v.match(/^([\:\d]){8}/g)||[''])[0]);

0: "03:47:06"
1: "03:47:07"
2: "03:47:08"
3: "03:47:09"
4: ""
5: "03:47:10"
6: "03:47:11"
7: ""

And if you need to match anywhere, then just remove ^ from the regex:

string_of_text.split('\n').map(v=>(v.match(/([\:\d]){8}/g)||[''])[0]);

0: "03:47:06"
1: "03:47:07"
2: "03:47:08"
3: "03:47:09"
4: ""
5: "03:47:10"
6: "03:47:11"
7: "03:33:12"

Explanation:

string_of_text
  .split('\n') // Split into an array of lines.
  .map( // Replace each entry with a new one using the given function.
     v => ( v.match(/([\:\d]){8}/g) || [''] )[0] // Each array item (v) is searched for the pattern.
                                                 // If not found, null is returned, so default to an array with an empty string.
   );

Upvotes: 1

Ricardo Ferreira
Ricardo Ferreira

Reputation: 616

This one solve your problem and select only this specific pattern:

/([\:\d]){8}/g

See the life code in the link below:

Live example

Upvotes: 0

Related Questions