阅读推荐--Behind Closed Door

最近找到了由Johanna Rothman写的<Behind Closed Door>,终于抽出一些时间读了一下。没想到竟然一气读完,欲罢不能。这确实是一本好书,以新上任的经理说起, 逐步将所有工作理顺的过程。

全书没有讲大道理,只有点点滴滴的小技巧。细节决定成败是一句被滥用的话,不过整本书都在讲细节,如何定位问题,分析问题,方法和工具,还有一些最佳实践。针对性非常强,见招拆招,最后的总结提出的方法和理论更是显示了作者在管理方面的造诣。

 

为什么这本书没有引人注目?也许顶级管理类书籍关注的都是高层面的主题,谈论的都是创新性管理。而本书只谈小擒拿,读者定位为中层管理,也没有什么创新的东西。全部都是实用技巧,很有效。帮我解决了很多问题,最重要的是指明了解决问题的方向,这个远远比那些理论重要的多。

 

在此,向专注于技术,但又有心向管理方向发展的朋友们强烈推荐此书--<Behind Closed Door>.同时,作者的网站也有不少文章很精彩。读完之后,请记得与大家分享你的收获。

<think>我们正在处理一个正则表达式的错误:"look-behind requires fixed-width pattern"。这个错误通常发生在使用Python的`re`模块时,当在正则表达式中使用了变长的后视断言(lookbehind assertion)时会出现。因为Python的`re`模块要求后视断言(包括正向后视`(?<=...)`和负向后视`(?<!...)`)必须是固定宽度的模式,即模式匹配的字符串长度必须是固定的,不能是变长的。 例如,以下模式是允许的(固定宽度): `(?<=abc)` -> 宽度为3 `(?<=a|b)` -> 宽度为1(因为每个分支都是1个字符) 而以下模式是不允许的(变宽): `(?<=a*)` -> `a*`可以匹配任意长度(包括0) `(?<=a+)` -> `a+`可以匹配1个或多个,长度不固定 `(?<=a{1,3})` -> 匹配1到3个a,长度不固定 解决方案: 1. 如果可能,将变长的后视断言改为固定宽度。例如,如果使用量词(`*`, `+`, `{m,n}`等),需要确保匹配的字符串长度是固定的。如果分支中的选项长度不同,那么需要重写表达式,使其变为固定宽度。 2. 另一种方法是使用其他正则表达式特性来代替变长后视。例如,我们可以使用捕获组,并在匹配后提取所需的部分。 3. 如果使用的是`regex`第三方模块(而不是标准的`re`模块),它支持变长的后视断言。可以通过安装`regex`模块(`pip install regex`)并使用它来代替`re`。 下面我们分别用例子说明: 假设我们遇到的正则表达式错误是因为使用了变长的后视,例如: ```python pattern = r'(?<=a+)b' ``` 这个模式会引发错误:`re.error: look-behind requires fixed-width pattern` 我们可以尝试以下方法: 方法一:改为固定宽度(如果可行) 如果我们的意图是匹配前面有一个或多个'a'的'b',且我们只关心固定长度的'a'(比如说,我们最多允许3个'a'),那么我们可以写成: ```python pattern = r'(?<=a)' # 匹配一个a,固定宽度1 # 或者 pattern = r'(?<=a{1,3})' # 但是这样仍然是变宽的,不允许!所以只能拆分成多个固定宽度的后视 ``` 但是,如果我们要求前面的a是1个到3个,那么我们不能使用`{1,3}`,因为它是变长的。我们可以写成多个分支: ```python pattern = r'(?:(?<=a)|(?<=aa)|(?<=aaa))b' ``` 这样,每个后视都是固定宽度的(1、2、3)。 方法二:避免使用后视,使用捕获组 我们可以匹配前面的'a'和后面的'b',然后只提取'b',但这样会改变匹配结果的结构。例如: ```python pattern = r'(a+)(b)' # 然后我们匹配后,使用group(2)来获取b ``` 但是注意,这会匹配连续的a和b,并且捕获它们。如果我们需要的位置是b的位置,那么这种方法可能适用。 方法三:使用`regex`模块 ```python import regex pattern = r'(?<=a+)b' text = "aaab" match = regex.search(pattern, text) if match: print(match.group(0)) # 输出 'b' ``` 因为`regex`模块支持变长的后视(和前瞻)断言,所以这是一个可行的解决方案。 根据实际需求选择合适的方法。 下面我们用一个具体的示例来展示如何解决: 假设我们想匹配所有前面有等号(=)的单词,但等号前面可能有空格(空格数量不定),所以可能会写出: ```python pattern = r'(?<=\s*=)\w+' ``` 这里`\s*`表示0个或多个空格,是变宽的,所以会报错。 我们可以改为: - 使用固定宽度的后视(如果我们知道空格的最大数量,可以拆分支,但通常不知道) - 或者使用捕获组: ```python pattern = r'\s*=(\w+)' # 然后提取group(1) ``` - 或者使用`regex`模块。 这里我们用捕获组的方法: ```python import re text = "name = value" pattern = r'\s*=(\w+)' match = re.search(pattern, text) if match: print(match.group(1)) # 输出 'value' ``` 或者使用`regex`模块: ```python import regex text = "name = value" pattern = r'(?<=\s*=)\w+' match = regex.search(pattern, text) if match: print(match.group(0)) # 输出 'value' ``` 总结:解决“look-behind requires fixed-width pattern”错误的方法主要有两种: 1. 重写正则表达式,避免使用变长后视(改为固定宽度或者用捕获组)。 2. 使用第三方`regex`模块代替标准`re`模块,它支持变长的后视断言。 根据实际情况选择。 </think>### 解决"look-behind requires fixed-width pattern"错误的方法 这个错误发生在 Python 正则表达式中,当你使用**变长后视断言**(variable-length lookbehind)时会出现。Python 的 `re` 模块要求后视断言(`(?<=...)` 或 `(?<!...)`)必须有**固定宽度匹配模式**。以下是详细解决方案: #### 1. **理解核心问题** 后视断言必须匹配**固定长度**的字符串。以下情况会引发错误: ```python import re # 错误示例:变长模式(使用 * 或 +) re.search(r'(?<=a*)b', 'cb') # 报错:look-behind requires fixed-width pattern re.search(r'(?<=\w+)b', 'ab') # 同样报错 ``` #### 2. **解决方案** ##### 方法一:改用固定宽度模式 将变长量词(`*`, `+`, `?`, `{m,n}`)替换为固定宽度: ```python # 正确:固定宽度匹配 re.search(r'(?<=a{2})b', 'aab') # 匹配成功(固定2个字符) re.search(r'(?<=\s{3})b', ' b') # 匹配3个空格后的b ``` ##### 方法二:使用捕获组替代 用捕获组提取内容,代替后视断言: ```python text = "price: $100" # 错误方式:变长后视 # pattern = r'(?<=\$\s*)\d+' # 正确替代:捕获组 match = re.search(r'\$\s*(\d+)', text) if match: print(match.group(1)) # 输出: 100 ``` ##### 方法三:使用分支结构 将变长模式拆分为多个固定宽度的分支: ```python # 匹配 a 或 aa 后的 b re.search(r'(?:(?<=a)|(?<=aa))b', 'aab') # 匹配成功 ``` ##### 方法四:使用第三方 regex 模块 安装支持变长后视的增强正则模块: ```bash pip install regex ``` 代码示例: ```python import regex # 第三方库 # 支持变长后视 match = regex.search(r'(?<=\$\s*)\d+', 'price: $100') print(match.group(0)) # 输出: 100 ``` #### 3. **关键原则** - **固定宽度要求**:后视断言必须匹配确定长度的字符串,例如: - 允许:`(?<=ab)`, `(?<=a|b)`, `(?<=\d{3})` - 禁止:`(?<=a*)`, `(?<=\w+)`, `(?<=\d{1,3})` - **前瞻不限宽**:前瞻断言(`(?=...)`)无此限制 #### 4. **错误排查流程** 1. 检查正则表达式中的后视断言 `(?<=...)` 或 `(?<!...)` 2. 确认内部模式是否包含变长量词(`*`, `+`, `?`, `{m,n}`) 3. 选用上述四种解决方案之一修改 > **何时选择第三方库?** > 当必须使用复杂变长后视且无法重构正则表达式时,推荐 `regex` 模块。否则优先使用固定宽度或捕获组方案保持兼容性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值