user3120188
user3120188

Reputation: 63

JavaScript regex to get separated matches between two phrases

What is a regex pattern I can use to parse the following text:

Mission m1
"Mission a is completing exam"
End Mission
Something is not necessary
Task t1
"Task b is keeping house"
comment: "... End Task"
End Task
abc
Task t2
Do something
End Task

.. so that it looks like the following :

[1]:
Mission m1
"Mission a is completing exam"
End Mission

[2]:
Task t2
Do something
End Task

[3]:
Task t2
Do something
End Task

I tried this regex pattern \b(?:Mission|Task)\b(.|\n)*\b(?:Mission|Task)\b - the problem is that it only returns one result containing both of three parts.

Upvotes: 2

Views: 86

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626923

This is a complete rewrite of the previous answer because your input is quite different from what you showed in the beginning.

You need a simple regex matching a string between two strings:

/^(Mission|Task)\b[\s\S]*?^End \1$/mg

Here is an unrolled version of the same regex:

/^(Mission|Task)\b.*(?:\r?\n(?!End \1).*)*\r?\nEnd \1$/gm

See the regex demo

Details:

  • ^ - start of a line
  • (Mission|Task)\b - either Mission or Task whole words
  • [\s\S]*? - any 0+ chars, as few as possible up to the first...
  • ^End \1$ - End, space and the word captured into Group 1, as a whole line.

Upvotes: 2

kabanus
kabanus

Reputation: 25895

Your regex seems OK, though probably (^|\n)(Mission|Task) is enough for your needs (Find all lines starting with 'Mission' or 'Task'. The reason is I don't think your end goal needs to match the entire paragraph - see below). Your main problem is probably that you don't use a global modifier:

pattern=/(^|\n)(Mission|Task)/g;

Another problem is (I think) you're XYing this. I think the above regex and replace would be easier here, but since you want a different replacement for each match you can't just use replace:

yourText.replace(pattern,constantString)

You can work around this using a function and a global var:

var index = 1;
yourText.replace(pattern,function(x){ return "P"+(index++)+"\n"+x;})

Note the /g will cause replace to work on all matches in string. If you still want to use your pattern just add /g.

EDIT forgot to post the fiddle.

Upvotes: 1

Related Questions