Py学习  »  Python

此python代码如何使用regex sub()和group()将字符串转换为camelCase?

kuku • 4 年前 • 525 次点击  

我是个新手,请放轻松点:) 这是我在网上找到的解决方案 codewars

import re
def to_camel_case(text):
    return re.sub('[_-](.)', lambda x: x.group(1).upper(), text)
  • 我查找了re.sub()和group(),但仍然无法将其组合在一起。我不知道怎么做 [_-](.) 工作,为什么 [_-](w+) 不起作用?
  • 他是怎么学会用sub连字符和下划线的?那么,
  • 成功地将每个单词的第一个字符大写 除了第一个字 ?
  • 我想 x.group(1).upper() 将整个单词大写,为什么组(1)指的是第一个字符?
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50972
 
525 次点击  
文章 [ 2 ]  |  最新文章 4 年前
James Mchugh
Reply   •   1 楼
James Mchugh    4 年前

所以要理解这段代码,您必须理解一点正则表达式和一点 re Python module . 我们先看看 re.sub 做。从文档来看,函数的签名如下

re.sub(pattern, repl, string, count=0, flags=0)

重要的是 pattern , repl ,和 string 参数。

  • 图案 是要替换的正则表达式模式
  • 回复 是要将匹配的模式替换为的,可以是以匹配对象作为参数的字符串或函数
  • 一串 是要替换的字符串

函数用于查找 一串 符合正则表达式的 图案 ,并将这些部分替换为 回复 .

现在让我们进入使用的正则表达式: [_-](.) .

  • [_-] 匹配方括号中的任何字符( _ - )
  • . 匹配任何字符
  • (.) 捕获 capture group

现在让我们把这一切放在一起。完整的模式将匹配两个字符。第一个字符将是 _ - 第二个角色可以是任何东西。实际上,以下字符串的粗体部分将被匹配。

  • _t型 世界
  • 测试 _3个
  • 游牧-
  • 这个遗嘱 _米 阿奇
  • 正常人_
  • 需要 _米 矿石 _c类 创造性的 _e类 示例-

重要的是 (.) regex的一部分匹配任何字符并将其存储在捕获组中,这允许我们在 回复 部分论点。

我们来看看 回复 就在这里。在这种情况下, 回复 是一个 lambda function .

lambda x: x.group(1).upper()

lambda与普通的Python函数没有太大区别。在冒号之前定义参数,然后在冒号之后定义返回表达式。上面的羔羊 x 作为一个论点,它假设 是一个 match object . 匹配对象具有 group 方法,该方法允许您引用与regex模式匹配的组(请记住 (.) 从以前开始?)。它获取匹配的第一组,并使用 str 对象的内置 upper 方法。然后它返回大写的字符串,这就是替换匹配的 图案 .

现在一起:

import re
def to_camel_case(text):
    return re.sub('[_-](.)', lambda x: x.group(1).upper(), text)

这个 图案 [_-](.) 它匹配任何下划线或破折号后跟任何字符。使用 回复 lambda函数。部分 一串 然后将匹配该模式的字符替换为大写字符。

最后,我认为以上回答了您的大部分问题,但总结一下:

我查找了re.sub()和group(),但仍然无法将其组合在一起。我不知道怎么做 [_-](.) 工作,为什么 [_-](w+) 不起作用?

我想你是想用 \w 字符集,而不是 w . 这个 \西 字符集匹配所有字母数字字符和下划线。如果 + 未使用运算符。这个 + 贪婪地匹配字符,因此它将导致属于 \西 设置要捕获的下划线或连字符后面的内容。这会导致两个问题:它将所有捕获的字符(可能是一个完整的单词)大写,并捕获下划线,导致以后的下划线无法正确替换。

他是怎么学会用sub连字符和下划线的?

赋予 回复 只返回第一个捕获组的大写版本。在模式中 [-_](.) ,只捕获连字符或下划线后面的字符。实际上,模式 [-_](.) 匹配并替换为大写字符 (.) . 这就是连字符/下划线被删除的原因。

是否成功地将每个单词的第一个字符(第一个单词除外)大写? 我以为x.group(1).upper()会将整个单词大写,为什么group(1)指的是第一个字符?

捕获组只匹配下划线或连字符后面的第一个字符,因此这是大写的。

Aggragoth
Reply   •   2 楼
Aggragoth    4 年前

我会尽量用外行的话来解释这个解决方案。

所以首先, re.sub() 搜索指定模式的出现 '[_-](.)' 它将匹配连字符所在的任何子字符串 '-' 或下划线 '_' 就在另一个角色之前。这个 回复:sub() 函数然后分别通过匿名函数(lambda函数)运行这些匹配。

python中的Regex分组本质上涉及那些大括号 () 收集子表达式以供以后在程序中使用。lambda函数将接收一些从搜索中生成的regex对象 text 对于提供的模式,然后返回 x.group(1).upper() ,我们可以从正则表达式中看到,分组元素是连字符或下划线后面的单个字符,这是函数返回和替换的内容。

现在,回答你的要点:

为什么不 [_-](\w+) 工作? 这是因为,当它找到一个hypen时,它会选择它后面的所有字母数字字符,因此它会将下一个单词的整个大写。

他是如何用sub去掉连字符和下划线的? 这很容易回答。这个 回复:sub() 函数替换整个匹配项,而不仅仅是分组元素,在lambda中,他只返回大写的分组元素,而不返回连字符。

成功地将每个单词的第一个字符大写(除了第一个单词)? 当搜索regex模式时,它将查找 立即进行 连字符或下划线,并且第一个单词之前不包含这两个字符中的任何一个。如果你给这个函数提供 '-hello-there' 它将产生: 'HelloThere'

我以为x.group(1).upper()会将整个单词大写,为什么group(1)指的是第一个字符? 这取决于模式,因为模式是 '[_-](.)' 而不是 '[_-](.+)' ,它只匹配一个字符

我希望这对你有所帮助