【问题标题】:get all occurences from a string based on find pattern in python根据python中的查找模式从字符串中获取所有出现
【发布时间】:2021-06-06 05:50:56
【问题描述】:

假设我有一个这样的字符串:

exp = 'CASE WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'CPU\'  THEN   \'YES\'  WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'RAM\'  THEN   \'YES\' ELSE  \'NO\' END' 
exp2 = 'CASE WHEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0  THEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE") ELSE ("Expressions"."ORDER_ITEMS"."QUANTITY"+ "Expressions"."ORDER_ITEMS"."UNIT_PRICE")   END '

我想返回所有出现的 WHEN 和 THEN 以及相应的文本。

这是exp1的预期输出

['WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'CPU\'  THEN   \'YES\'','WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'RAM\'  THEN   \'YES\'']

这是exp2的预期输出

['WHEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0  THEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE")']

我试过的是这样的:

res = re.findall(r'\s*(WHEN|When|when)+\s*(.*)\s*(THEN|Then|then)+\s*')

但结果列表在我的例子中显示了这个输出

['(WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'CPU\'  THEN   \'YES\'  WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'RAM\'  THEN)']

【问题讨论】:

    标签: python regex re


    【解决方案1】:

    试试:

    WHEN (?:(?! +(?:WHEN|ELSE)).)* # with flags=re.I
    
    1. WHEN - 匹配 'WHEN'
    2. (?:(?! +(?:WHEN|ELSE)).) - 使用负前瞻,并声明只要当前位置不匹配一个或多个空格字符后跟“WHEN”或“ELSE”,则再匹配一个字符。

    See Regex Demo

    import re
    
    cases = [
        'CASE WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'CPU\'  THEN   \'YES\'  WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'RAM\'  THEN   \'YES\' ELSE  \'NO\' END',
        'CASE WHEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0  THEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE") ELSE ("Expressions"."ORDER_ITEMS"."QUANTITY"+ "Expressions"."ORDER_ITEMS"."UNIT_PRICE")   END '
    ]
    
    for case in cases:
        res = re.findall(r'WHEN (?:(?! +(?:WHEN|ELSE)).)*', case, flags=re.I)
        print(res)
    

    打印:

    ['WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'CPU\'  THEN   \'YES\'', 'WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'RAM\'  THEN   \'YES\'']
    ['WHEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0  THEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE")']
    

    更新

    如果您想对 WHEN 和 ELSE 部分进行分组(去掉前导和尾随空格),请使用以下正则表达式:

    WHEN +(.*?) +THEN +((?:(?! +(?:WHEN|ELSE)).)*)
    
    import re
    
    cases = [
        'CASE WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'CPU\'  THEN   \'YES\'  WHEN  "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"=\'RAM\'  THEN   \'YES\' ELSE  \'NO\' END',
        'CASE WHEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0  THEN  ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE") ELSE ("Expressions"."ORDER_ITEMS"."QUANTITY"+ "Expressions"."ORDER_ITEMS"."UNIT_PRICE")   END '
    ]
    
    for case in cases:
        results = re.findall(r'WHEN +(.*?) +THEN +((?:(?! +(?:WHEN|ELSE)).)*)', case, flags=re.I)
        for result in results:
            print(result[0], result[1])
    

    打印:

    "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"='CPU' 'YES'
    "Expressions"."PRODUCT_CATEGORIES"."CATEGORY_NAME"='RAM' 'YES'
    ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0 ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE")
    

    【讨论】:

    • Hye.. CASE WHEN ("Expressions"."ORDER_ITEMS"."QUANTITY"*"Expressions"."ORDER_ITEMS"."UNIT_PRICE")>0 THEN ("Expressions"."ORDER_ITEMS"."QUANTITY"* "Expressions"."ORDER_ITEMS"."UNIT_PRICE") ELSE ("Expressions"."ORDER_ITEMS"."QUANTITY"+ "Expressions"."ORDER_ITEMS"."UNIT_PRICE") END 在这种情况下它不起作用,因为我们可以在 THEN 之后使用空格字符。请解决此问题
    • 我不太关注。用新的输入和预期的输出更新您的问题并且您需要清楚地指定一条规则,说明何时停止扫描。在您可以推断出规则是在看到 THEN 后跟空格之后,您然后扫描下一组非空格字符然后停止。例如,当您看到下一次出现 WHEN 或字符串结尾时停止。
    • 更新了我的问题和 exp2 所需的输出。场景在 THEN 关键字之后,中间也可以有空格字符。因为我们指定了 \S+,所以这个测试用例失败了。
    • 我认为当whenelse关键字出现时我们应该停止扫描。我们该怎么做
    • 我要出去一会儿,等我回来看看这个。
    猜你喜欢
    • 2012-10-12
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    相关资源
    最近更新 更多