首页 > 解决方案 > Python:在动态文本中查找字符串并将另一个文本放在行前

问题描述

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

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 文本出现之前添加了新文本!<\b> session.findById("wnd[1]").sendVKey 0

(...)

尝试使用 re.sub、re.findall 和替换,但我认为这不是一个好方法。我的工作代码如下,但它不是动态的(在 .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)

标签: pythonregexreplacefindfindall

解决方案


检查子字符串是否在字符串中的最简单方法是使用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, but 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 中相对较慢)。但是对于大多数可以完成这项工作的中型应用程序来说。


推荐阅读