如何在群组找到时更换群组?

时间:2021-12-03 21:05:17

I need to transform strings that follow the structure:

我需要转换遵循结构的字符串:

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

<3位> [字母[m位数[罗马数字]]] [k个字母] 位数>

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

有点像<3位>。 [(字母)[(m位数)[(罗马数字)]]] [ - k个字母] 位>

Those strings are, for example:

这些字符串是,例如:

  • "121100" - nothing interesting at the end
  • “121100” - 最后没有什么有趣的

  • "121100N" - should be transformed to "121.100(N)"
  • “121100N” - 应转换为“121.100(N)”

  • "121100N20" - should be transformed to "121.100(N)(20)"
  • “121100N20” - 应改为“121.100(N)(20)”

  • "121100N20VII" - should be transformed to "121.100(N)(20)(VII)"
  • “121100N20VII” - 应改为“121.100(N)(20)(VII)”

  • "121100NTAIL" - should be transformed to "121.100(N)-TAIL"
  • “121100NTAIL” - 应转换为“121.100(N)-TAIL”

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)

所以团体是1美元 - 第一个3位数块,2美元 - 其他数字,3美元 - 字母,4美元 - 字母后数字(如果有的话),5美元 - 罗马数字(如果有的话),8美元 - 字符串的其余部分(如果有的话) )

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?

所以“121100N” - 变成“121.100(N)()() - ”而不是想要“121.100(N)”。如果找到该组,我怎么才能放括号?

2 个解决方案

#1


1  

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

#2


1  

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}`;
}

#1


1  

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

#2


1  

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}`;
}