【问题标题】:Python: find strings inside dynamic text and put another text in front of the linePython:在动态文本中查找字符串并将另一个文本放在行前
【发布时间】:2020-06-16 22:19:34
【问题描述】:

我试图找到/构建一个解决方案,但目前对我来说太复杂了。我有一个来自 SAP 的文本(存储在 tkinter 的 scrooledtext 中。

session.findById("wnd[0]").sendVKey 4
session.findById("wnd[1]/tbar[0]/btn[17]").press
session.findById("wnd[1]/usr/tabsG_SELONETABSTRIP/tabpTAB001/ssubSUBSCR_PRESEL:SAPLSDH4:0220/sub:SAPLSDH4:0220/ctxtG_SELFLD_TAB-LOW[3,24]").setFocus
session.findById("wnd[1]").sendVKey 0
session.findById("wnd[1]/usr/lbl[1,1]").setFocus
session.findById("wnd[1]").sendVKey 33

我想在 .sendVKey 发生时找到每一行,并将 newtext 放在行首(或行上方) - 例如,有 3 行:

在 sendkey 文本出现之前添加了新文本! session.findById("wnd[0]").sendVKey 4

(...) 在 sendkey 文本出现之前添加了新文本! session.findById("wnd[1]").sendVKey 0

(...)

尝试使用 re.sub、re.findall 和 replace,但我认为这不是一个好方法。我的工作代码如下,但它不是动态的(在 .sendVkey 方法中,它可以是(“wnd [1]”)中的不同窗口(0、1、2、3 等)。任何提示/解决方案?请帮助 :(

    def multiple_replace(string, rep_dict):
        pattern = re.compile("|".join([re.escape(k) for k in sorted(rep_dict, key=len, reverse=True)]), flags=re.DOTALL)
        return pattern.sub(lambda x: rep_dict[x.group(0)], string)


    date_div = RPAcode.get("1.0", tk.END)
    delay_vba_function = "   Added new text before sendkey text occurs"
"
    replaced_text = multiple_replace(date_div, {'.sendVKey' : '\n' + delay_vba_function + '\n' + '.sendVKey', \
                                                'session.findById("wnd[1]").sendVKey' : '\n' + delay_vba_function + '\n' + 'session.findById("wnd[1]").sendVKey', \
                                                'session.findById("wnd[2]").sendVKey' : '\n' + delay_vba_function + '\n' + 'session.findById("wnd[2]").sendVKey', \
                                                'session.findById("wnd[3]").sendVKey' : '\n' + delay_vba_function + '\n' + 'session.findById("wnd[3]").sendVKey'})
    #print(replaced_text)

    RPAcode.delete('0.0', tk.END) #Deletes previous data
    RPAcode.insert(1.0, replaced_text)

【问题讨论】:

    标签: python regex replace find findall


    【解决方案1】:

    检查子字符串是否在字符串中的最简单方法是使用in-运算符(至少在Python3.5中)。考虑以下几点:

    text = 'session.findById("wnd[0]").sendVKey 4'
    if '.sendVKey' in text:
        text = '(...)' + text
    text
    

    如果你在终端运行它,输出将是:

    '(...)session.findById("wnd[0]").sendVKey 4'
    

    因此,如您所见,脚本甚至已经在文本行前面添加了一些文本。如果您不说text = '(...)' + text,而是说text = '(...)\n' + text,则(...) 将显示在实际文本上方的一行中。如果您将上述代码示例放入遍历所有文本行的 for 循环中,我认为这种方法可能会解决您的问题。

    编辑:

    在遍历行之前,您首先必须将文本拆分为行。我想这正是你所需要的:

    text = """session.findById("wnd[0]").sendVKey 4
    session.findById("wnd[1]/tbar[0]/btn[17]").press
    session.findById("wnd[1]/usr/tabsG_SELONETABSTRIP/tabpTAB001/ssubSUBSCR_PRESEL:SAPLSDH4:0220
    session.findById("wnd[1]").sendVKey 0
    session.findById("wnd[1]/usr/lbl[1,1]").setFocus
    session.findById("wnd[1]").sendVKey 33"""
    
    query_text = ".sendVKey"
    addition = "(...) "
    
    def indicate_lines(text, query_text, indication):
        result = ''
        text = text.splitlines()
        for line in text:
            if query_text in line:
                result = result + indication + line + "\n"
            else:
                result = result + line + "\n"
        return result
    
    result = indicate_lines(text, query_text, addition)
    print(result)
    

    结果会是:

    (...) session.findById("wnd[0]").sendVKey 4
    session.findById("wnd[1]/tbar[0]/btn[17]").press
    session.findById("wnd[1]/usr/tabsG_SELONETABSTRIP/tabpTAB001
    /ssubSUBSCR_PRESEL:SAPLSDH4:0220
    (...) session.findById("wnd[1]").sendVKey 0
    session.findById("wnd[1]/usr/lbl[1,1]").setFocus
    (...) session.findById("wnd[1]").sendVKey 33
    

    请注意,如果您想要一个可扩展的解决方案,我希望正则表达式执行得更快(因为for-loops 在 Python 中相对较慢)。但是对于大多数可以完成这项工作的中型应用程序来说。

    【讨论】:

    • 感谢 Daniel B 这部分工作。我使用了您提到的方法:code delay_vba_function = " Call vbaDELAYTIME \n" text = RPAcode.get("1.0", tk.END) if '.sendVKey' in text: text = delay_vba_function + text RPAcode.delete ('0.0', tk.END) #Deletes previous data RPAcode.insert(1.0, text) code 但不幸的是 Python 只更改了第一次出现(我有 3 个 sendVKey 出现)。结果应该改变 session.findById("wnd[1]").sendVKey 0 和 session.findById("wnd[1]").sendVKey 33 也...
    • 您的带有循环的解决方案效果很好 :) 非常感谢 :) 我以为我必须使用一些循环,但我不知道该怎么做(我在 VBA 中编写了很多程序,但是这些2 是不同的语言,有很多相似之处)
    • 不客气!请不要忘记将问题标记为已回答。我的效率主要关注您想要处理千兆字节(或更多)文本的应用程序。但只要不是这种情况,for 循环确实是最方便和最方便的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    相关资源
    最近更新 更多