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


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') :

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

한마디로 :

의 대신 단어 경계를 찾는 생각한 \b후 TEXTO당신은 문자열과 일치 할 \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.