Dmitry Samoylov
Dmitry Samoylov

Reputation: 1318

How to replace groups only if the group found?

I need to transform strings that follow the structure:

<3 digits><n digits>[letter[m digits[Roman number]]][k letters]

to sometging like <3 digits>.<n digits>[(letter)[(m digits)[(Roman number)]]][- k letters]

Those strings are, for example:

I made a regexp

^(\d{3})(\d*)(\D)(\d*)((XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$)?(.*$)?

So the groups are $1 - first 3-digit chunk, $2 - other digits, $3 - letter, $4 - number after letter (if any), $5 - Roman number (if any), $8 - the rest of the string (if any)

Now I need to use only non-empty groups. My current substitution puts parentheses and the dash symbol no matter if anything was found:

$1.$2($3)($4)($5)-$8

So "121100N" - becomes "121.100(N)()()-" instead of wanted "121.100(N)". How can I put parentheses only if the group was found?

Upvotes: 0

Views: 354

Answers (2)

KevBot
KevBot

Reputation: 18898

You can pass the matches off to a function, and transform your string there by checking if a match exists for that capture group. If there is no match, then output an empty string.

let reg = /(\d{3})(\d*)([A-Z])(\d+)?((?:XC|XL|L?X{0,3})(?:IX|IV|V?I{0,3}))?([A-Z]+)?/;
let strings = ["121100", "121100N", "121100N20", "121100N20VII", "121100NTAIL"];

strings = strings.map(str => {
  let match = str.match(reg);
  return (match) ? transform(match.splice(1)) : str;
});

console.log(strings);

function transform(m) {
  let p0 = m[0];
  let p1 = m[1];
  let p2 = (m[2]) ? `(${m[2]})` : '';
  let p3 = (m[3]) ? `(${m[3]})` : '';
  let p4 = (m[4]) ? `(${m[4]})` : '';
  let p5 = (m[5]) ? `-${m[5]}` : '';

  return `${p0}.${p1}${p2}${p3}${p4}${p5}`;
}

Upvotes: 1

user5734441
user5734441

Reputation:

You may just have to do a second expression that searches for the empty capture groups and removes the parentheses and the dash.

Find:

\(\)|-$

Replace:

replace with nothing

Upvotes: 1

Related Questions