假设我有一个这样的字符串:
input_string = "foo ab-123 ab-456"
字符串我想通过用通用的东西替换每个ab-xxx组来清理它,但是 * 只有 * 整个字符串以“foo”开头。如果只有一个组,我可以这样做(在Python中):
pattern = re.sub(r"(?<=foo) (ab-\d{3})", "<ab-xxx>", input_string)
型但是,我如何为所有群体做到这一点,并牢记积极的落后条件?
2hh7jdfx1#
它必须是一个正则表达式吗?如果没有,您可以将任务分为两个步骤:
s = "foo ab-123 ab-456" if s.startswith("foo"): s = re.sub(r"ab-\d{3}", "<ab-xxx>", s)
字符串上面的例子给出了s = foo <ab-xxx> <ab-xxx>。
foo <ab-xxx> <ab-xxx>
nfs0ujit2#
如果你想让所有的事情都在一次调用中发生,你可以使用回调:
import re def apply_masking(string): masked = re.sub( r'ab-\d{3}', lambda match: '<ab-xxx>' if match.string.startswith('foo') else match[0], string ) return masked
字符串请注意,每次找到匹配时都会调用回调,这意味着它将多次检查条件。此外,这段代码并不完全可读,而"readability counts"。话虽如此,你可能想使用@Socowi建议的解决方案。或者,如果你不介意使用第三方模块和/或相对复杂的正则表达式,你可以使用regex模块来实现其非固定宽度的lookbehind功能:
regex
import regex def apply_masking(string): masked = regex.sub(r'(?<=^foo.*)ab-\d{3}', '<ab-xxx>', string) return masked
(?<=^foo.*) # Match but only if the whole string starts with "foo". ab-\d{3} # "ab-" and 3 digits
的数据on regex101.com(ECMAScript)或者,如果您更喜欢PCRE的\K和\G:
\K
\G
(?: # Match either ^foo # "foo" at the start of the string | # or \G(?!^) # the position at the end of the previous match ) # followed by .*? # anything, as few as possible, \K # (all of which we forfeit entirely) ab-\d{3} # then "ab-" and 3 digits.
型on regex101.com(PCRE2)
2条答案
按热度按时间2hh7jdfx1#
它必须是一个正则表达式吗?如果没有,您可以将任务分为两个步骤:
字符串
上面的例子给出了s =
foo <ab-xxx> <ab-xxx>
。nfs0ujit2#
如果你想让所有的事情都在一次调用中发生,你可以使用回调:
字符串
请注意,每次找到匹配时都会调用回调,这意味着它将多次检查条件。此外,这段代码并不完全可读,而"readability counts"。话虽如此,你可能想使用@Socowi建议的解决方案。
或者,如果你不介意使用第三方模块和/或相对复杂的正则表达式,你可以使用
regex
模块来实现其非固定宽度的lookbehind功能:的数据
on regex101.com(ECMAScript)
或者,如果您更喜欢PCRE的
\K
和\G
:型
on regex101.com(PCRE2)