0

I have this project name in Jenkins:

dir1/dir2/dir3/projectname

now, I want to extract and save each dir [dir1,dir2,dir3] to a different variable also project name. e.g: var1: dir1, var2: dir2, var3: dir3,projectname: projectname I used a lot of regexes but sadly I can't yet. my last effort is:

/(.*)//

But it does not work properly.

pyramid13
  • 266
  • 1
  • 5
  • 21

1 Answers1

1

If the number of directories is fixed then you could use this regex:

(?<var1>[^\/]+)\/(?<var2>[^\/]+)\/(?<var3>[^\/]+)\/(?<projectname>[^\/]+)

You can test it here: https://regex101.com/r/neV5UU/1/

The concept is to use named groups with the (?<groupname> ) syntax. I prefer searching for any char except the slash with the pattern [^\/] (slash has to be escaped as it is used to start and finish the regex) instead of .* which matches anything.

Example of it running in JavaScript:

const regex = /(?<var1>[^\/]+)\/(?<var2>[^\/]+)\/(?<var3>[^\/]+)\/(?<projectname>[^\/]+)/g;
let output = '';

const paths = [
  'dir1/dir2/dir3/projectname',
  'first/second/third/another-project-name'
];

paths.forEach(path => {
  output += `${path}\n`;
  let m;
  while ((m = regex.exec(path)) !== null) {
    Object.keys(m.groups).forEach((name, index) => {
      output += `${name} = ${m.groups[name]}\n`;
    });
  }
  output += "\n";
});

document.getElementById('output').innerText = output;
<pre id="output"></pre>

But I presume that you'll have a different path length. So in this case you may just use a regex to match items between the slashes and you know that the last one is your project name.

const regex = /[^\/]+/g;
let output = '';

const paths = [
  'dir1/dir2/dir3/projectname',
  'first/second/third/fourth/another-project-name'
];

paths.forEach(path => {
  output += `${path}\n`;
  let m;
  let pieces = [];
  while ((m = regex.exec(path)) !== null) {
    pieces.push(m[0]);
  }
  let projectName = pieces.pop();
  pieces.forEach(piece => {
    output += `path item = ${piece}\n`;
  });
  output += `project name = ${projectName}\n\n`;
});

document.getElementById('output').innerText = output;
<pre id="output"></pre>
Patrick Janser
  • 3,318
  • 1
  • 16
  • 18
  • thanks, I need another thing, I want to saved only `var2`, and `var1` and `var3` and `projectname` removed. actually, ignore them – pyramid13 Dec 14 '21 at 06:16
  • @pyramid13 Well, your question wasn't very clear a week ago! So if I understand you just need a regex that matches the second part of the path? If yes, then `(?<=^[^\/]+\/)[^\/]+(?=\/.*)` will find it. I'm using a positive lookbehind with `(?<=^[^\/]+\/)` to find a starting string, some chars wich are not a slash, then a slash. This means that what we are looking for is preceded by the first folder and slash. Then `[^\/]+` is to match your desired folder number 2. And the last positive lookahead `(?=\/.*)` is to only match folder 2 if it's followed by a slash and then any char. – Patrick Janser Dec 14 '21 at 07:21
  • Sorry, @patrick did you check this regex yourself?? I have syntax error – pyramid13 Dec 14 '21 at 08:48
  • Oh, I see that it depends on the regex engine. Effectively, it works with ECMAScript but not with PCRE because the lookbehind hasn't got a fixed size due to the `+`. Can you use groups? if yes then we could use `^[^\/]+\/([^\/]+)\/.*` and then you read or replace it by the group number 1 with `$1` or `\1` depending on your engine. Test it here: https://regex101.com/r/dICHYc/1 – Patrick Janser Dec 14 '21 at 09:23
  • I found another regex.I got help regex101.com chat. with `/(?[^/]+)\/.*/` extract `dir1` with `/^[^\/]+\/([^\/]+)/` extract `dir2` – pyramid13 Dec 15 '21 at 11:21
  • @pyramid13: effectively, your regex to capture dir2 is the same as the one I mentioned in the previous comment. – Patrick Janser Dec 15 '21 at 20:36