You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python re.sub实现iframe连续编号?解决变量绑定错误

Fixing the UnboundLocalError in re.sub with Counter

Let's break down why you're running into these errors and fix them with clean, concise solutions that fit your requirements.

Why the Original Code Fails

When you write num = num + 1 inside your regex function, Python automatically treats num as a local variable. But you’re trying to reference num (on the right side of the assignment) before it’s defined locally—hence the UnboundLocalError.

Your attempt to use global was on the right track, but you had the order wrong: you can’t assign to num before declaring it as global.


Solution 1: Correct Global Variable Usage

Fix the global declaration order, and adjust your regex to properly capture full URLs (your original (\w+) won’t match URLs with :// or dots):

import re

num = 0
def regex_match(m):
    global num  # Declare num as global FIRST
    num += 1
    # Use f-strings for cleaner, more readable formatting
    return f'<iframe src="{m.group(1)}/number/{num}">'

source = '<p>hogehogehello<br />aaaa</p><iframe src="https://youtube.com/hogehgoe"><div><strong><h1>aa</h1></strong></div><iframe src="https://youtube.com/foo"><iframe src="https://youtube.com/bar"><h2>aaaaaa</h2><iframe src="https://youtube.com/baz">'
processed_source = re.sub(r'<iframe src="([^"]+)">', regex_match, source)
print(processed_source)

This will output exactly what you want, with each iframe's src appended with /number/1, /number/2, etc.


Solution 2: Cleaner Approach Without Global Variables (Shorter Code)

Global variables can introduce unwanted side effects, so a better (and shorter) way is to use itertools.count to create an auto-incrementing iterator. This avoids global variables entirely and keeps your code tight:

import re
from itertools import count

source = '<p>hogehogehello<br />aaaa</p><iframe src="https://youtube.com/hogehgoe"><div><strong><h1>aa</h1></strong></div><iframe src="https://youtube.com/foo"><iframe src="https://youtube.com/bar"><h2>aaaaaa</h2><iframe src="https://youtube.com/baz">'

# Create a counter starting at 1
counter = count(1)
# Use a lambda to handle matches and increment the counter on each hit
processed_source = re.sub(r'<iframe src="([^"]+)">', lambda m: f'<iframe src="{m.group(1)}/number/{next(counter)}">', source)

print(processed_source)

How This Works:

  • count(1) generates an infinite iterator that starts at 1 and increments by 1 each time you call next() on it.
  • The lambda function runs once per match, calling next(counter) to get the next sequential number and inserting it into the replacement string.

This is the shortest, most maintainable solution that meets your "no finditer" requirement.


内容的提问来源于stack exchange,提问作者Clifford Fox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:44:32