user463535
user463535

Reputation:

Regex to match string between two words, where the ending boundary word is optional

I'm trying to match text between the words called and with but also still match even if with is missing. e.g.

In this sentence, I want to match Mary Jane

"Create a picklist called Mary Jane with the value ox."

Here I want still to match Mary Jane, even without a with clause afterwards

Create a picklist Mary Jane.

My regex only matches when with is present, but not if it is absent.

"Create a picklist called Mary Jane with the value ox'".match(/called(.*)(?:with)/i) // Matches "Mary Jane"

"Create a picklist called Mary Jane'".match(/called(.*)(?:with)/i) // Error: Does not match anything

How can I write a regex that can match both cases?

Upvotes: 0

Views: 55

Answers (2)

The fourth bird
The fourth bird

Reputation: 163362

To match the name without the leading spaces and without the dot, you might use a capturing group with an alternation:

\bcalled (.*?)(?: with|\.?$)
  • \bcalled Match literally preceded with a word boundary
  • (.*?) Capture group 1, match any char except a newline non greedy
  • (?: Non capturing group
    • with Match literally
    • | Or
    • \.?$ Match an optional dot and assert end of the string
  • ) Close non capturing group

Regex demo

Upvotes: 1

Akshay Bande
Akshay Bande

Reputation: 2587

You can do it like this. This is what I came up with. I hope it helps.

let str1 = "Create a text field called Mary Jane with ninja";

let str2 = "Create a text field called Mary Jane";

console.log(words(str1));
console.log(words(str2));

function words(str){


  let arr = str.split(" ");
  let i = arr.indexOf("called");
  let j  = arr.indexOf("with");
  if( j == -1){
    return arr.slice(i+1);
  }
  return arr.slice(i+1,j);
}

Upvotes: 0

Related Questions