用括号围绕python字符串中的模式

用括号围绕python字符串中的模式,python,regex,Python,Regex,我有一个字符串,看起来像这样: oldString="this is my {{string-d}}" => "this is my {{(string-d)}}" oldString2="this is my second{{ new_string-d }}" => "this is my second{{ (new_string-d) }}" oldString2="this is my second new_string-d " => "this is my second

我有一个字符串,看起来像这样:

oldString="this is my {{string-d}}" => "this is my {{(string-d)}}"
oldString2="this is my second{{ new_string-d }}" => "this is my second{{ (new_string-d) }}"
oldString2="this is my second new_string-d " => "this is my second (new_string-d) "
oldString2="this is my second new[123string]-d " => "this is my second (new[123string]-d) "
每当我看到“-d”就在它后面和它所附加的单词之前时,我想添加括号

我编写了一个代码,在字符串中查找模式“-d”,并在找到模式后将字符串划分为“-d”之前、“-d”之后和“-d”本身的3个分区,然后检查“-d”之前的块,直到找到空格或“{”,并停止并添加括号。我的代码如下所示: 另外,我从他们那里读取了很多文件,并试图修改其中的字符串。上面的示例只是为了演示我要做的事情

   if ('-d') in oldString:
    p = oldString.partition('-d')
    v = p[p.index('-d')-1]
    beforeString=''
    for i in reversed(v):
        if i != ' ' or i != '{':
            beforeString=i+beforeString 
            indexNew = v.index(i)
    outPutLine = v[:indexNew]+'('+v[indexNew:]
    newString = outPutLine + '-d' + ' )'
    print newString
运行代码的结果将是:

newString = "(this is my {{string-d )"
正如你所看到的,起始括号在“this”之前,而不是在“string”之前。为什么会发生这种情况?而且,我不确定这是否是进行此类查找和替换的最佳方式。如果您有任何建议,我将不胜感激

>>> import re
>>> oldString = "this is my {{string-d}}"
>>> oldString2 = "this is my second{{ new_string-d }}"
>>> re.sub(r"(\w*-d)", r"(\1)", oldString)
'this is my {{(string-d)}}'
>>> re.sub(r"(\w*-d)", r"(\1)", oldString2)
'this is my second{{ (new_string-d) }}'
请注意,假设一个单词仅由字母、数字和下划线组成,则这与“单词”匹配


下面是对正在发生的事情的更彻底的分解:

  • 字符串文本前面的
    r
    表示该字符串是“原始字符串”。它阻止Python将字符解释为转义序列。例如,
    r“\n”
    是一个斜杠,后跟字母n,而不是被解释为一个换行符。我喜欢在正则表达式模式中使用原始字符串,尽管它并不总是必需的
  • \w*-d
    周围的括号是一个捕获组。它向正则表达式引擎指示应保存该组的内容以供以后使用
  • 序列
    \w
    表示“任何字母数字字符或下划线”
  • *
    表示“前面的项目为零或多个”。
    \w*
    一起表示“字母数字字符或下划线为零或多个”
  • -d
    表示“连字符后跟字母d”
总之,
(\w*-d)
表示“零个或多个字母数字字符或下划线,后跟连字符和字母d。保存所有这些字符以备将来使用。”

第二个字符串描述了应该用什么替换匹配的数据。“\1”表示“第一个捕获组的内容”。括号只是普通的括号。总之,
(\1)
在本上下文中表示“从捕获组中获取保存的内容,将其括在括号中,然后将其放回字符串中”


如果要匹配的字符不止是字母数字和下划线,那么可以将
\w
替换为任何要匹配的字符集合

>>> re.sub(r"([\w\.\[\]]*-d)", r"(\1)", "{{startingHere[zero1].my_string-d }}")
'{{(startingHere[zero1].my_string-d) }}'
如果还希望匹配以“-d()”结尾的单词,可以将括号对与
\(\)
匹配,并使用
将其标记为可选

>>> re.sub(r"([\w\.\[\]]*-d(\(\))?)", r"(\1)", "{{startingHere[zero1].my_string-d() }}")
'{{(startingHere[zero1].my_string-d()) }}'
请注意,假设一个单词仅由字母、数字和下划线组成,则这与“单词”匹配


下面是对正在发生的事情的更彻底的分解:

  • 字符串文本前面的
    r
    表示该字符串是“原始字符串”。它阻止Python将字符解释为转义序列。例如,
    r”\n“
    是一个斜杠,后跟字母n,而不是被解释为一个换行符。我喜欢在正则表达式模式中使用原始字符串,尽管它并不总是必需的
  • \w*-d
    周围的括号是一个捕获组。它向正则表达式引擎指示应保存该组的内容以供以后使用
  • 序列
    \w
    表示“任何字母数字字符或下划线”
  • *
    表示“前面的项目为零或多个”。
    \w*
    一起表示“字母数字字符或下划线为零或多个”
  • -d
    表示“连字符后跟字母d”
总之,
(\w*-d)
表示“零个或多个字母数字字符或下划线,后跟连字符和字母d。保存所有这些字符以备将来使用。”

第二个字符串描述了应该用什么替换匹配的数据。“\1”表示“第一个捕获组的内容”。括号只是普通的括号。总之,
(\1)
在本上下文中表示“从捕获组中获取保存的内容,将其括在括号中,然后将其放回字符串中”


如果要匹配的字符不止是字母数字和下划线,那么可以将
\w
替换为任何要匹配的字符集合

>>> re.sub(r"([\w\.\[\]]*-d)", r"(\1)", "{{startingHere[zero1].my_string-d }}")
'{{(startingHere[zero1].my_string-d) }}'
如果还希望匹配以“-d()”结尾的单词,可以将括号对与
\(\)
匹配,并使用
将其标记为可选

>>> re.sub(r"([\w\.\[\]]*-d(\(\))?)", r"(\1)", "{{startingHere[zero1].my_string-d() }}")
'{{(startingHere[zero1].my_string-d()) }}'

如果希望括号仅发生在双花括号内,则需要类似以下内容:

oldString="this is my {{string-d}}" => "this is my {{(string-d)}}"
oldString2="this is my second{{ new_string-d }}" => "this is my second{{ (new_string-d) }}"
oldString2="this is my second new_string-d " => "this is my second (new_string-d) "
oldString2="this is my second new[123string]-d " => "this is my second (new[123string]-d) "
re.sub(r'({\s*)([^}]*-d)(\s*}'),r'\1(\2)\3',s)
把它分解一下:

#目标模式
r'({\s*)([^}]*-d)(\s*}}
#^^^^^^捕获组1,打开{{加上可选空间
#^^^^^^捕获组2,非大括号加-d
#^^^^^^捕获3,空格加上结束}
替换的
r'\1(\2)\3'
只是将组组装起来,并使用 中间的括号

综合起来:

重新导入
def quote_字符串_d(s):
返回re.sub(r'({\s*)([^}]*-d)(\s*}'),r'\1(\2)\3',s)
打印(quote_string_d(“这是我的{{string-d}”))
打印(quote_string_d(“这是我的第二个{{new_string-d}”))
打印(引用字符串d(“不应引用其他字符串d”))
输出:

这是我的{(string-d)}
这是我的第二个{(新字符串-d)}
不应引用其他字符串-d

注意,第三个实例没有得到括号,因为它不在
{{}

内。如果希望括号仅在双花括号内出现,则需要类似以下内容:

oldString="this is my {{string-d}}" => "this is my {{(string-d)}}"
oldString2="this is my second{{ new_string-d }}" => "this is my second{{ (new_string-d) }}"
oldString2="this is my second new_string-d " => "this is my second (new_string-d) "
oldString2="this is my second new[123string]-d " => "this is my second (new[123string]-d) "