根据函数输出替换字符串

Gau*_*don 8 python regex

所以,输入:

accessibility,random good bye
Run Code Online (Sandbox Code Playgroud)

我想要输出:

a11y,r4m g2d bye
Run Code Online (Sandbox Code Playgroud)

所以,基本上,我必须以下列格式缩写所有长度大于或等于4的单词: first_letter + length_of_all_letters_in_between + last_letter

我试着这样做:

re.sub(r"([A-Za-z])([A-Za-z]{2,})([A-Za-z])", r"\1" + str(len(r"\2")) + r"\3", s)
Run Code Online (Sandbox Code Playgroud)

但它不起作用.在JS,我会很容易做到:

str.replace(/([A-Za-z])([A-Za-z]{2,})([A-Za-z])/g, function(m, $1, $2, $3){
   return $1 + $2.length + $3;
});
Run Code Online (Sandbox Code Playgroud)

我如何在Python中做同样的事情?

编辑:我不能丢失原始字符串中的任何标点符号.

Cu3*_*O42 7

你在JavaScript中做的事情当然是正确的,你传递的是匿名函数.你在Python中做的是传递一个常量表达式("\ 12\3",因为len(r"\2")在函数调用之前进行求值),它不是一个可以为每个匹配计算的函数!

虽然Python中的匿名函数不像JS中那样有用,但它们可以在这里完成工作:

>>> import re
>>> re.sub(r"([A-Za-z])([A-Za-z]{2,})([A-Za-z])", lambda m: "{}{}{}".format(m.group(1), len(m.group(2)), m.group(3)), "accessability, random good bye")
'a11y, r4m g2d bye'
Run Code Online (Sandbox Code Playgroud)

这里发生的是为每个替换调用lambda,获取匹配对象.然后我检索所需的信息并从中构建替换字符串.

  • @Kasra怎么样?它完全符合作者的要求,并且与他在JS中的代码非常相似 (4认同)

Blc*_*ght 3

您遇到的问题是len(r'\2')始终是2,而不是正则表达式中第二个捕获组的长度。您可以使用lambda表达式创建一个函数,该函数的工作方式与您在 JavaScript 中使用的代码类似:

re.sub(r"([A-Za-z])([A-Za-z]{2,})([A-Za-z])",
       lambda m: m.group(1) + str(len(m.group(2)) + m.group(3),
       s)
Run Code Online (Sandbox Code Playgroud)

mlambda 的参数是一个对象match,对其group方法的调用相当于您之前使用的反向引用。

仅使用不带捕获组的简单单词匹配模式可能会更容易(group()仍然可以不带参数调用来获取整个匹配的文本):

re.sub(r'\w{4,}', lambda m: m.group()[0] + str(len(m.group())-2) + m.group()[-1], s)
Run Code Online (Sandbox Code Playgroud)