parse string with regualr expression with version number in js

Viewed 31

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"] 
2 Answers

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

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.
Related