简体   繁体   English

如何在python中通过正则表达式替换/修改模式?

[英]How to replace/modify a pattern by regular expression in python?

Assume that I want to modify all patterns in a script, take one line as an example: 假设我想修改脚本中的所有模式,以一行为例:

line = "assert Solution().oddEvenList(genNode([2,1,3,5,6,4,7])) == genNode([2,3,6,7,1,5,4]), 'Example 2'"

Notice that function genNode is taking List[int] as the parameter. 请注意,函数genNodeList[int]作为参数。 What I want is to remove the List, and keep the all the integers in the list, so that the function is actually taking *nums as the parameters. 我想要的是删除List,并保持列表中的所有整数,以便该函数实际上将*nums作为参数。

Expecting: 期待:

line = "assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'"

I've come up with a re pattern 我想出了一个re模式

r"([g][e][n][N][o][d][e][(])([[][0-9\,\s]*[]])([)])"

but I am not sure how I could use this... I can't get re.sub to work as it requires me to replace with a fixed string. 但我不确定如何使用它...我无法让re.sub工作,因为它需要我用固定的字符串替换。

How can I achieve my desired result? 我怎样才能达到理想的效果?

You can do: 你可以做:

re.sub(r'(genNode\()\[([^]]+)\]', r'\1\2', line)
  • (genNode\\() matches genNode( and put it in captured group 1 (genNode\\()匹配genNode(并将其放入捕获的组1中
  • \\[ matches literal [ \\[匹配文字[
  • ([^]]+) matches upto next ] , and put it in captured group 2 ([^]]+)匹配到下一个] ,并将其放入捕获的组2中
  • \\] matches literal ] \\]匹配文字]

In the replacement, we've used the captured groups only ie dropped [ and ] . 在替换中,我们仅使用捕获的组,即丢弃[]


You can get rid of the first captured group by using a zero-width positive lookbehind to match the portion before [ : 您可以通过使用零宽度正向lookbehind来匹配第一个捕获的组,以匹配[ :之前的部分:

re.sub(r'(?<=genNode\()\[([^]]+)\]', r'\1', line)

Example: 例:

In [444]: line = "assert Solution().oddEvenList(genNode([2,1,3,5,6,4,7])) == genNode([2,3,6,7,1,5,4]), 'Example 2'"                                                                                         

In [445]: re.sub(r'(genNode\()\[([^]]+)\]', r'\1\2', line)                                                                                                                                                  
Out[445]: "assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'"

In [446]: re.sub(r'(?<=genNode\()\[([^]]+)\]', r'\1', line)                                                                                                                                                 
Out[446]: "assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'"

FWIW, using typical non-greedy pattern .*? FWIW,使用典型的非贪婪模式.*? instead of [^]]+ would work as well: 而不是[^]]+也会起作用:

re.sub(r'(?<=genNode\()\[(.*?)\]', r'\1', line)

Instead of writing [g][e][n][N][o][d][e][(] you could write getNode\\( 而不是写[g][e][n][N][o][d][e][(]你可以写getNode\\(

The current character class that you use [0-9\\,\\s]* matches 0+ times any of the listed which could also for example match only comma's and does not make sure that there are comma separated digits. 您使用的当前字符类[0-9\\,\\s]*匹配列出的任何列表的0+次,例如也可以仅匹配逗号,并且不确保存在逗号分隔的数字。

To match the comma delimiter integers, you could match 1+ digits with a repeating group to match a comma and 1+ digits. 要匹配逗号分隔符整数,您可以将1+位与重复组匹配以匹配逗号和1+位。

At the end use a positive lookahead to assert for the closing parenthesis or capture it in group 3 and also use that in the replacement. 最后使用正向前瞻来断言右括号或在第3组中捕获它并在替换中使用它。

With this pattern use r'\\1\\2 as the replacement. 使用此模式使用r'\\1\\2作为替换。

(genNode\()\[(\d+(?:,\d+)*)\](?=\))

Explanation 说明

  • (genNode\\() Capture in group 1 matching genNode( (genNode\\()捕获第1组匹配genNode(
  • \\[ Match [ \\[匹配[
  • ( Capturing group 2 (捕获第2组
    • \\d+(?:,\\d+)* Match 1+ digits and repeat 0+ times a comma and 1+ digits (to also support a single digit) \\d+(?:,\\d+)*匹配1+位数并重复0次以上逗号和1位数字(也支持单个数字)
  • ) Close group 2 )关闭第2组
  • \\] Match ] \\]比赛]
  • (?=\\)) Positive lookahead, assert what is on the right is a closing parenthesis ) (?=\\))正向前瞻,断言右边的是一个右括号)

Python demo | Python演示 | Regex demo 正则表达式演示

For example 例如

import re

regex = r"(genNode\()\[(\d+(?:,\d+)*)\](?=\))"
line = "assert Solution().oddEvenList(genNode([2,1,3,5,6,4,7])) == genNode([2,3,6,7,1,5,4]), 'Example 2'"
result = re.sub(regex, r"\1\2", line)

if result:
    print (result)

Result 结果

assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM