簡體   English   中英

Python字符串文字到正則表達式對象

[英]Python string literal to regex object

我有一個返回字符串"r'^A Plat'"的函數,該字符串被寫入文本文件

get_Pat(file)
    #process text file and now returns "r'^A Plat'"

最初,我在代碼內部進行了硬編碼。

pat = r'^A Plat'
use(pat)

現在

pat = get_Pat(file)
use(pat)

但它的抱怨,因為我想它的字符串,而不是正則表達式對象。

我努力了

re.escape(get_Pat(file))

re.compile(get_Pat(file))

但它們都不起作用

如何將字符串文字轉換為正則表達式對象?

r'^ A Plat'是否等效於re.compile(“ A Plat”)? 愚蠢的問題,也許

如果它use("^A Plat'")
如果它的use("r'^A Plat'") <--- get_Pat(file)吐出了什么,則不起作用

我想我的任務只是將字符串r'^ A Plat'轉換為^ A Plat。
但是我覺得這只是一個廉價的黑客。

r'^A Plat'是相同的'^A Plat'r r代表raw而不是regex。 它使您可以編寫帶有特殊字符(如\\字符串,而不必對其進行轉義。

>>> r'^A Plat'
'^A Plat'
>>> r'/ is slash, \ is backslash'
'/ is slash, \\ is backslash'
>>> r'write \t for tab, \n for newline, \" for double quote'
'write \\t for tab, \\n for newline, \\" for double quote'

原始字符串通常在編寫正則表達式時使用,因為正則表達式通常包含反斜杠,否則應將其轉義。 r 創建regex對象,雖然。

Python手冊

第2.4.1節 字符串文字

字符串文字可以選擇以字母'r''R'開頭; 這樣的字符串稱為原始字符串,並使用不同的規則來解釋反斜杠轉義序列。

...

除非存在'r''R'前綴,否則將根據類似於標准C使用的規則來解釋字符串中的轉義序列。

不確定“什么都不起作用”是什么意思,但是re.compile()是您要尋找的內容:

>>> def getPat():
...     return r'^A Plat'
...
...
>>> getPat()
'^A Plat'
>>> reObj = re.compile(getPat())
>>> reObj
<_sre.SRE_Pattern object at 0x16cfa18>
>>> reObj.match("A Plat")
<_sre.SRE_Match object at 0x16c3058>
>>> reObj.match("foo")

編輯:

使用此代碼返回后,您可以消除多余的r' '殘留:

>>> s = "r'^A Plat'"
>>> s = s[1:].strip("'")
>>> s
'^A Plat'

根據您的get_pat函數中的注釋,其返回:

“ r'^ A Plat'”

這不是您認為得到的:

>>> x = re.compile("r'^A Plat'")
>>> y = "A Plat wins"
>>> x.findall(y)
[]
>>> x = re.compile("^A Plat")
>>> x.findall(y)
['A Plat']
>>>

因此,您使用的正則表達式不是r'^ A Plat',而是“ r'^ A Plat'”,r'^ A Plat'可以:

>>> x = re.compile(r'^A Plat')
>>> x.findall(y)
['A Plat']

要解決此問題,我將必須了解您首先如何在字符串中獲取“ r'^ A Plat'”。

from ast import literal_eval
pat = literal_eval(get_Pat(file))

編輯

aelon,

正如您在評論中所寫,您不能導入literal_eval() ,我的上述解決方案對您沒有用。 此外,盡管表達了有趣的信息,但其他答案並沒有帶來其他解決方案。
因此,我提出了一個新的建議,而不是使用literal_eval()

import re

detect = re.compile("r(['\"])(.*?)\\1[ \t]*$")

with open('your_file.txt') as f:
    pat = f.readline()

if detect.match(pat):
    r = re.compile(detect.match(pat).group(2))
else:
    r = re.compile(pat)

說明:

假設有連續的字符r'^Six o\\'clock\\nJim'寫為* r'^Six o\\'clock\\nJim' *的第一行

* your_file *第一行的打開和讀取會創建對象pat
-其類型是<type 'str'>在Python 2和<class 'str'>在Python 3
-其表示形式為"r'^Six o\\'clock\\nJim'"
-它的值是r'^Six o\\'clock\\nJim' ,也就是說,字符r'^Six o\\'clock\\nJim
如果文件中有第二行,則末尾可能還會有“字符” \\n 在文件中寫入的r'^Six o\\'clock\\nJim'的末尾與其行尾之間可能還有空白或制表符,誰知道?。 這就是為什么我關閉正則表達式模式以使用[ \\t]*$定義detect的原因。
因此,我們可能會在感興趣的字符之后獲得其他可能的空白,制表符和換行符,然后如果我們print tuple(pat)我們將獲得例如:

('r', "'", '^', 'S', 'i', 'x', ' ', 'o', '\\', "'", 'c', 'l', 'o', 'c', 'k', '\\', 'n', 'J', 'i', 'm', "'", ' ', ' ', ' ', '\t', '\n')

現在,讓我們考慮使用表達式detect.match(pat).group(2)獲得的對象。
它的值是^Six o\\'clock\\nJim ,由18個字符組成, \\'n是三個不同的字符,其中沒有一個轉義字符\\'和一個轉義字符\\n
這個值與我們通過寫指令rawS = r'^Six o\\'clock\\nJim'來獲得名稱為rawS的對象rawS的值完全相同rawS = r'^Six o\\'clock\\nJim'
然后,通過直接寫r = re.compile(detect.match(pat).group(2)) ,我們可以獲得正則表達式,該正則表達式的模式以r'....'的形式寫入文件中。
在我的示例中,文件中寫入的字符序列中只有序列\\'\\n 但是所有在此之前的內容對於該語言的任何轉義序列均有效。

換句話說,我們不必懷疑一個函數會與來自STRING的"r'^Six o\\'clock\\nJim'" r'^Six o\\'clock\\nJim'的EXPRESSION r'^Six o\\'clock\\nJim' "r'^Six o\\'clock\\nJim'"的功能相同值r'^Six o\\'clock\\nJim'
我們直接將r'^Six o\\'clock\\nJim'作為detect.match(pat).group(2)的字符串的值。

Nota Bene

在Python 2中,類型<type 'str'>是有限字符集的類型。
它是文件讀取內容的類型,在模式'r'和模式'rb'也可以打開。

在Python 3中,類型<class 'str'>涵蓋了Unicode字符。
但是與Python 3相反,以模式'r'打開的文件的讀取內容的類型為<type 'str'>
如果文件以'rb'模式打開,則其類型為<class 'bytes'>

然后,我認為上面的代碼在Python 3和Python 2中都可以正常工作,因此可以使用'r'模式打開該文件。

如果應使用'rb'打開文件,則應將正則表達式模式更改為b"r(['\\"])(.*?)\\\\1[ \\t]*\\r?\\n"

AFAIHU

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM