정규식 내에서 변수를 사용하는 방법은 무엇입니까?


235

variable내부 를 사용하고 싶습니다 regex. 어떻게 할 수 Python있습니까?

TEXTO = sys.argv[1]

if re.search(r"\b(?=\w)TEXTO\b(?!\w)", subject, re.IGNORECASE):
    # Successful match
else:
    # Match attempt failed

9
문자열 연결을 사용합니다
Chris Eberle

답변:


52

python 3.6부터는 Literal String Interpolation , "f-strings"를 사용할 수 있습니다 . 특별한 경우 해결책은 다음과 같습니다.

if re.search(rf"\b(?=\w){TEXTO}\b(?!\w)", subject, re.IGNORECASE):
    ...do something

편집하다:

특수 문자를 다루는 방법에 대한 의견에 몇 가지 질문이 있었으므로 대답을 확장하고 싶습니다.

원시 문자열 ( 'r') :

정규 표현식에서 특수 문자를 처리 할 때 이해해야하는 주요 개념 중 하나는 문자열 리터럴과 정규 표현식 자체를 구별하는 것입니다. 여기에 잘 설명되어 있습니다 .

한마디로 :

의 대신 단어 경계를 찾는 생각한 \bTEXTO당신은 문자열과 일치 할 \boundary. 당신은 작성해야합니다 :

TEXTO = "Var"
subject = r"Var\boundary"

if re.search(rf"\b(?=\w){TEXTO}\\boundary(?!\w)", subject, re.IGNORECASE):
    print("match")

이것은 우리가 원시 문자열을 사용하기 때문에 작동합니다 (정규식 앞에 'r'이옵니다). 그렇지 않으면 정규식에 "\\\\ boundary"를 써야합니다 (4 개의 백 슬래시). 또한 '\ r'이 없으면 \ b '는 더 이상 단어 경계로 변환되지 않고 백 스페이스로 변환됩니다!

다시 탈출 :

기본적으로 특수 문자 앞에 백 스페이스를 넣습니다. 따라서 TEXTO에 특수 문자가 필요한 경우 다음을 작성해야합니다.

if re.search(rf"\b(?=\w){re.escape(TEXTO)}\b(?!\w)", subject, re.IGNORECASE):
    print("match")

참고 : 모든 버전의 경우> = 파이썬 3.7 : !, ", %, ', ,, /, :, ;, <, =, >, @, 및 `입니다 탈출하지. 정규 표현식에서 의미가있는 특수 문자 만 여전히 이스케이프 처리됩니다. _Python 3.3 이후로 이스케이프되지 않습니다. (s. here )

중괄호 :

f- 문자열을 사용하는 정규식 내에서 한정자를 사용하려면 이중 중괄호를 사용해야합니다. TEXTO와 정확히 두 자리 숫자를 일치시키고 싶다고 가정 해 봅시다.

if re.search(rf"\b(?=\w){re.escape(TEXTO)}\d{{2}}\b(?!\w)", subject, re.IGNORECASE):
    print("match")

2
2020 년 현재, 이것은 정규 표현식 내에서 변수를 사용하는 가장 단순하고 가장 파이썬적인 방법입니다.
CONvid19

3
이것은 확실히 와우 입니다.
Jason Goal

2
누군가 "rf"의 중요성을 여기에서 설명 할 수
있습니까

1
@HarshaReddy : 'r':이 문자열은 원시 문자열입니다. 사용하지 않으면 '\ b'가 백 스페이스 문자로 변환됩니다 ( docs.python.org/3/howto/regex.html#more- 패턴 전력 ). 'f'는 파이썬에게 이것이 'f-string'이라고 알려줍니다. 위 링크를 통해 중괄호에 변수를 쓸 수 있습니다.
공중

2
f- 문자열로 수량자를 작성하는 방법 : fr"foo{{1,5}}"(중괄호 두 배)
PunchyRascal

281

정규식을 문자열로 작성해야합니다.

TEXTO = sys.argv[1]
my_regex = r"\b(?=\w)" + re.escape(TEXTO) + r"\b(?!\w)"

if re.search(my_regex, subject, re.IGNORECASE):
    etc.

사용에 유의하십시오 re.escape 텍스트에 특수 문자가 포함되어 있으면, 그들은 이와 같이 해석되지 않도록합니다.


4
변수가 먼저 가면 어떻게됩니까? r'' + foo + 'bar'?
deed02392

r''당신이 할 경우 @ deed02392 필요하지 않습니다 re.escape(foo), 어쨌든해야합니다. 실제로, 나는 re당신이 접두사에 관계없이 유니 코드 문자열로 주어진 것을 해석 한다고 생각 합니다 r.
OJFord

re.escape 대신 .format ()이 작동합니까 아니면 re.escape ()가 필요합니까?
Praxiteles

@ praxiteles 대답을 찾았습니까?
CONvid19

2
이것이 작동하는지 잘 모르겠습니다. 변수가 속한 그룹이 필요합니다. 아래의 다른 답변은 더 직관적으로 보이며 정규 표현식을 여러 표현으로 나누지 마십시오.
guival

48
if re.search(r"\b(?<=\w)%s\b(?!\w)" % TEXTO, subject, re.IGNORECASE):

이것은 TEXTO에있는 것을 정규식에 문자열로 삽입합니다.



6

여러 개의 작은 패턴을 함께 묶어 정규 표현식 패턴을 작성하는 것이 매우 편리하다는 것을 알았습니다.

import re

string = "begin:id1:tag:middl:id2:tag:id3:end"
re_str1 = r'(?<=(\S{5})):'
re_str2 = r'(id\d+):(?=tag:)'
re_pattern = re.compile(re_str1 + re_str2)
match = re_pattern.findall(string)
print(match)

산출:

[('begin', 'id1'), ('middl', 'id2')]

4

다음을 제외하고 위의 모든 사항에 동의합니다.

sys.argv[1] 같은 것 Chicken\d{2}-\d{2}An\s*important\s*anchor

sys.argv[1] = "Chicken\d{2}-\d{2}An\s*important\s*anchor"

re.escape경우 정규 표현식처럼 동작하기를 원하기 때문에을 사용하고 싶지 않습니다.

TEXTO = sys.argv[1]

if re.search(r"\b(?<=\w)" + TEXTO + "\b(?!\w)", subject, re.IGNORECASE):
    # Successful match
else:
    # Match attempt failed

2

서로 비슷한 사용자 이름을 검색해야했으며 Ned Batchelder가 말한 내용이 매우 유용했습니다. 그러나 re.compile을 사용하여 다시 검색 용어를 만들 때 더 깨끗한 출력을 얻었습니다.

pattern = re.compile(r"("+username+".*):(.*?):(.*?):(.*?):(.*)"
matches = re.findall(pattern, lines)

다음을 사용하여 출력을 인쇄 할 수 있습니다.

print(matches[1]) # prints one whole matching line (in this case, the first line)
print(matches[1][3]) # prints the fourth character group (established with the parentheses in the regex statement) of the first line.

1

formatgrammer suger를 사용하여 다른 사용법을 시도 할 수 있습니다 .

re_genre = r'{}'.format(your_variable)
regex_pattern = re.compile(re_genre)  

0

format 키워드도 사용할 수 있습니다. Format 메서드는 {} 자리 표시자를 인수로 format 메서드에 전달한 변수로 바꿉니다.

if re.search(r"\b(?=\w)**{}**\b(?!\w)".**format(TEXTO)**, subject, re.IGNORECASE):
    # Successful match**strong text**
else:
    # Match attempt failed

0

더 많은 예

흐름 파일이있는 configus.yml이 있습니다.

"pattern":
  - _(\d{14})_
"datetime_string":
  - "%m%d%Y%H%M%f"

파이썬 코드에서 내가 사용하는

data_time_real_file=re.findall(r""+flows[flow]["pattern"][0]+"", latest_file)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.