我有以下文字:

<clipPath id="p54dfe3d8fa">
   <path d="M 112.176 307.8
L 112.176 307.8
L 174.672 270
L 241.632 171.72
L 304.128 58.32
L 380.016 171.72
L 442.512 217.08
L 491.616 141.48
L 491.616 307.8
z
"/>
  </clipPath>
  <clipPath id="p27c84a8b3c">
   <rect height="302.4" width="446.4" x="72.0" y="43.2"/>
  </clipPath>


我需要抓住这一部分:

d="M 112.176 307.8
L 112.176 307.8
L 174.672 270
L 241.632 171.72
L 304.128 58.32
L 380.016 171.72
L 442.512 217.08
L 491.616 141.48
L 491.616 307.8
z
"


我需要用其他内容替换此部分。我能够获取<clipPath ...><path d="[code i want]"/>的全部内容,但这对我没有帮助,因为我无法覆盖<clipPath>元素中的id。

请注意,还有其他我不想触摸的<clipPath>元素。我只想更改<path>元素内的<clipPath>元素。

我在想答案与选择clipPath元素之前的所有内容并在Path部分结束有关。任何帮助将不胜感激。

我一直在使用http://pythex.org/寻求帮助,并且还看到了奇怪的行为(与多行和空格有关),该行为与python 3.x代码之间的行为不同。

这是我尝试过的一些方法:

reg = r'(<clipPath.* id=".*".*>)'
reg = re.compile(r'(<clipPath.* id=".*".*>\s*<path.*d="(.*\n)+")')
reg = re.compile(r'((?<!<clipPath).* id=".*".*>\s*<path.*d="(.*\n)+")')

g = reg.search(text)
g

最佳答案

TL; DR:r'<clipPath.* id="[a-zA-Z0-9]+".*>\s*<path.*d=("(?:.*\n)+?")'

让我们分解一下...

您以:r'(<clipPath.* id=".*".*>\s*<path.*d="(.*\n)+")'开始,它将整个捕获模式包含在一个组中,因此整个元素将被捕获在match对象中。让我们删除那些括号:r'<clipPath.* id=".*".*>\s*<path.*d="(.*\n)+"'

接下来,您似乎经常使用.*,这很危险,因为它盲目贪婪。对于clipPath ID,如果您知道ID始终为字母数字,则更好的解决方案可能是r'<clipPath.* id="[a-zA-Z0-9]+".*>\s*<path.*d="(.*\n)+"'

最后,让我们看一下您实际想要捕获的内容。您的示例显示您想捕获引号,因此让它们进入捕获组:...*d=("(.*\n)+")。但是,这给我们留下了一个怪异的嵌套组情况,所以让我们使内部组不被捕获:...*d=("(?:.*\n)+")

现在我们正在捕获您想要的东西,但是仍然有一个问题...如果有多个满足这些条件的元素怎么办? +...*d=("(.*\n)+")的贪婪匹配将捕获它们之间的任何一行。我们在这里可以做的是通过在+之后加上?来使...*d=("(?:.*\n)+?")不贪心。

将所有这些东西放在一起:

r'<clipPath.* id="[a-zA-Z0-9]+".*>\s*<path.*d=("(?:.*\n)+?")'

10-06 01:57