1

I have string in two different format like following how to I write a RegExp in js to parse the information to get appName1-v10.20. under Package: ?

//example string
const twoMatchString = '\[Package: [appName1-v10.20.1](https://github.com/appName1/1111), [appName2-v20.15.10](https://github.com/appName2/aaa)\]\r\n[asdsad: asdas]\r\ni am description on PR'
const oneMatchString = '[Package: appName1-v10.20.1](https://github.com/appName1/1111)\r\n[asdsad: asdas]\r\ni am description on PR'
 
const reg = /\[Package:\s?(.+?,?)\]/g
const twoMatch = twoMatchString.matchAll(reg);
const oneMatch = oneMatchString.matchAll(reg);
console.log(twoMatch ) // wish to have ["appName1-v10.20.1", "appName2-v20.15.10"] 
console.log(oneMatch) // wish to have ["appName1-v10.20.1"] 
0

2 Answers 2

3

Using matchAll returns an RegExpStringIterator.

On this page there are examples how to get the values into an array using Array.from

If a positive lookbehind is supported (see this page for browser support):

(?<=\[Package:.*?)[^\s\][-]+-[^\][]+(?=])
  • (?<=\[Package:.*?) Assert [Package: to the left
  • [^\s\][-]+ Match a non whitspace char other than [ ] - or whitespace char
  • - Match -
  • [^\][]+ Match 1+ times any char other than [ and ]
  • (?=]) Positive lookahead to assert a ] to the right.

Regex demo

const oneMatchString = '\[Package: [appName1-v10.20.1](https://github.com/appName1/1111), [appName2-v20.15.10](https://github.com/appName2/aaa)\]\r\n[asdsad: asdas]\r\ni am description on PR'
const twoMatchString = '[Package: [appName1-v10.20.1](https://github.com/appName1/1111)\r\n[asdsad: asdas]\r\ni am description on PR'

const reg = /(?<=\[Package:.*?)[^\s\][-]+-[^\][]+(?=])/g;

const twoMatch = Array.from(twoMatchString.matchAll(reg), s => s[0]);
const oneMatch = Array.from(oneMatchString.matchAll(reg), s => s[0]);

console.log(twoMatch) //["appName1-v10.20.1", "appName2-v20.15.10"] 
console.log(oneMatch) // ["appName1-v10.20.1"]

Or a bit more strict version

(?<=\[Package:.*?)[^\s-]+-v\d+(?:\.\d+)*(?=])

regex demo

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

Comments

1

You can use

const extract = (text) => {
  const package = /\[Package:((?:,?\s*\[?[^\][]+]\([^()]*\))*)/.exec(text)?.[1]
  return package ? 
     Array.from(package.matchAll(/(?:^|\[)([^\][]*-v\d[^\][]*)]/g), x => x[1].trim()) : ""
}

See a JavaScript demo:

const extract = (text) => {
  const package = /\[Package:((?:,?\s*\[?[^\][]+]\([^()]*\))*)/.exec(text)?.[1]
  return package ? 
     Array.from(package.matchAll(/(?:^|\[)([^\][]*-v\d[^\][]*)]/g), x => x[1].trim()) : ""
}

const oneMatchString = '\[Package: [appName1-v10.20.1](https://github.com/appName1/1111), [appName2-v20.15.10](https://github.com/appName2/aaa)\]\r\n[asdsad: asdas]\r\ni am description on PR'
const twoMatchString = '[Package: appName1-v10.20.1](https://github.com/appName1/1111)\r\n[asdsad: asdas]\r\ni am description on PR'

console.log( extract(oneMatchString) ) // ["appName1-v10.20.1", "appName2-v20.15.10"] 
console.log( extract(twoMatchString) ) // ["appName1-v10.20.1"]

The \[Package:((?:,?\s*\[?[^\][]+]\([^()]*\))*) regex matches

  • \[Package: - [Package: string
  • ((?:,?\s*\[?[^\][]+]\([^()]*\))*) - Group 1: zero or more occurrences of the following pattern sequences:
    • ,?\s* - an optional , and zero or more whitespaces
    • \[? - an optional [
    • [^\][]+ - one or more chars other than [ and ]
    • ]\( - ]( string
    • [^()]* - zero or more chars other than ( and )
    • \) - a ) char.

The (?:^|\[)([^\][]*-v\d[^\][]*)] regex extracts the versions:

  • (?:^|\[) - string start or [
  • ([^\][]*-v\d[^\][]*) - Group 1: any zero or more chars other than [ and ], -v, a digit and again any zero or more chars other than [ and ]
  • ] - a ] char.

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.