如何用正则表达式忽略无IN_MEASUREMENT的FUNCTION数据集?
Absolutely! You can fix this with a single regex adjustment—no need for two separate searches. The issue with your original pattern is that it "leaks" across FUNCTION blocks: the .*? in your regex will match any characters (including across /end FUNCTION and into the next block) until it finds an IN_MEASUREMENT section, which is why it incorrectly associates the first FUNCTION with the second block's IN_MEASUREMENT content.
Fixed Regex Pattern
Here's the adjusted pattern that ensures we only match FUNCTION blocks that actually contain an IN_MEASUREMENT section, and stay within the boundaries of that single FUNCTION:
sSearch = r'/begin FUNCTION\s*(\S*)\s*"[^"]*"(?:(?!/end FUNCTION).)*?/begin IN_MEASUREMENT\s*(.*?)\s*/end IN_MEASUREMENT(?:(?!/end FUNCTION).)*?/end FUNCTION'
Breakdown of Key Changes
(?:(?!/end FUNCTION).)*?: This non-capturing group uses a negative lookahead assertion. It tells the regex to match characters one at a time, but only as long as those characters don't start the/end FUNCTIONsequence. This keeps the match confined to the current FUNCTION block, preventing it from spilling into the next one.- We removed the extra space before
/begin IN_MEASUREMENT(your original pattern had a space there which might cause issues with inconsistent formatting). - The pattern now strictly looks for
IN_MEASUREMENTinside the current FUNCTION block before matching the rest of the block up to/end FUNCTION.
Full Working Code
import re sFileContent = ''' /begin FUNCTION foo "a.1.2.3 footext" /begin SUB_FUNK fooo foobar foobar /end SUB_FUNK FUNK_VERSION "a.1.2.3" /end FUNCTION /begin FUNCTION foobarbarbar "SSV-TAG 3.1.0-3.1.0 foobarbarbar tex text_tex" /begin SUB_FUNK foobarbarbarfoo foobarbarbarfooo foobarbarbarfoooo /end SUB_FUNK /begin IN_MEASUREMENT barbar barfoo /end IN_MEASUREMENT /begin OUT_MEASUREMENT barfoobar barbarfoo /end OUT_MEASUREMENT /begin LOC_MEASUREMENT loc_barfoobar barbarfoo_loc /end LOC_MEASUREMENT FUNK_VERSION "3.1" /end FUNCTION''' sSearch = r'/begin FUNCTION\s*(\S*)\s*"[^"]*"(?:(?!/end FUNCTION).)*?/begin IN_MEASUREMENT\s*(.*?)\s*/end IN_MEASUREMENT(?:(?!/end FUNCTION).)*?/end FUNCTION' lMatches = re.findall(sSearch, sFileContent, re.S) print(lMatches)
Output
When you run this, you'll get the expected result:
[('foobarbarbar', 'barbar barfoo')]
This approach is efficient and clean—all logic is contained in one regex, so you don't need to loop through FUNCTION blocks and search each one separately.
内容的提问来源于stack exchange,提问作者mrCarnivore

