programing

정규식 일치 항목 일부 추출

projobs 2022. 10. 1. 14:28
반응형

정규식 일치 항목 일부 추출

HTML 페이지에서 제목을 추출하는 정규 표현을 원합니다.현재 가지고 있는 것은 다음과 같습니다.

title = re.search('<title>.*</title>', html, re.IGNORECASE).group()
if title:
    title = title.replace('<title>', '').replace('</title>', '') 

태그를 삭제하지 않아도 되도록 <title> 내용만 추출하는 정규 표현이 있습니까?

사용하다( )regexp 및 python에서 캡처된 re.search문자열을 가져옵니다( 반환됩니다).None결과를 찾을 수 없는 경우는, 직접 사용하지 말아 주세요).

title_search = re.search('<title>(.*)</title>', html, re.IGNORECASE)

if title_search:
    title = title_search.group(1)

에서 시작하는 것에 주의해 주세요.Python 3.8할당식 도입(PEP 572) (:=연산자)는 if 조건 내에서 직접 일치 결과를 변수로서 캡처하여 조건 본문에서 재사용함으로써 Krzysztof Kraso' 솔루션의 일부를 개선할 수 있다.

# pattern = '<title>(.*)</title>'
# text = '<title>hello</title>'
if match := re.search(pattern, text, re.IGNORECASE):
  title = match.group(1)
# hello

캡처 그룹 사용:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)

아름다운 수프를 추천해 드리겠습니다.Soup은 모든 html 문서를 해석하기 위한 매우 좋은 lib입니다.

soup = BeatifulSoup(html_doc)
titleName = soup.title.name

시험:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
re.search('<title>(.*)</title>', s, re.IGNORECASE).group(1)

제공된 코드 조각은 다음 사항을 처리하지 않습니다.Exceptions제안해도 될까요?

getattr(re.search(r"<title>(.*)</title>", s, re.IGNORECASE), 'groups', lambda:[u""])()[0]

패턴을 찾을 수 없거나 첫 번째 일치하는 경우 기본적으로 빈 문자열이 반환됩니다.

이것으로 충분하다고 생각합니다.

#!python
import re
pattern = re.compile(r'<title>([^<]*)</title>', re.MULTILINE|re.IGNORECASE)
pattern.search(text)

...텍스트(HTML)가 "text"라는 이름의 변수에 있다고 가정합니다.

또, HTML TITLE 태그내에 합법적으로 삽입할 수 있는 다른 HTML 태그가 없고, 그러한 컨테이너/블록내에 다른<문자를 합법적으로 삽입할 수 있는 방법이 없는 것을 전제로 하고 있습니다.

하지만...

Python에서 HTML 구문 분석에 정규 표현을 사용하지 마십시오.HTML 파서를 사용하세요! (다양한 HTML, SGML 및 XML 파서가 표준 라이브러리에 이미 있을 때 추가 및 중복 작업이 될 수 있는 완전한 파서를 쓰는 것이 아니라면).

"실제" 태그 수프 HTML(대부분 SGML/XML Validator에 적합하지 않음)을 취급하는 경우 BeautifulSoup 패키지를 사용하십시오.표준 라이브러리에는 없지만 이 용도로 널리 권장됩니다.

다른 옵션은 lxml...적절한 구조화(표준 준거) HTML용으로 작성되어 있습니다.단, BeautifulSoup을 파서로 사용할 수 있는 옵션이 있습니다.Element Soup.

현재 Krzysztof Kraso fails에 의해 가장 많이 투표된 답변은 다음과 같이 실패합니다.<title>a</title><title>b</title>또한 회선 길이 등의 이유로 회선 경계를 넘는 제목 태그는 무시됩니다.마지막으로, 에러가 발생합니다.<title >a</title>(유효한 HTML: XML/HTML 태그 내부의 공백).

따라서 다음과 같은 개선을 제안합니다.

import re

def search_title(html):
    m = re.search(r"<title\s*>(.*?)</title\s*>", html, re.IGNORECASE | re.DOTALL)
    return m.group(1) if m else None

테스트 케이스:

print(search_title("<title   >with spaces in tags</title >"))
print(search_title("<title\n>with newline in tags</title\n>"))
print(search_title("<title>first of two titles</title><title>second title</title>"))
print(search_title("<title>with newline\n in title</title\n>"))

출력:

with spaces in tags
with newline in tags
first of two titles
with newline
  in title

궁극적으로, 저는 HTML 파서를 추천하는 다른 사람들과 함께 갑니다 - 뿐만 아니라 HTML 태그의 비표준적인 사용을 다루기 위해서.

것이 필요했어요.package-0.0.1하지만 (이름, 버전)을는 안 .0.0.010.

regex101의 예를 참조해 주세요.

import re

RE_IDENTIFIER = re.compile(r'^([a-z]+)-((?:(?:0|[1-9](?:[0-9]+)?)\.){2}(?:0|[1-9](?:[0-9]+)?))$')

example = 'hello-0.0.1'

if match := RE_IDENTIFIER.search(example):
    name, version = match.groups()
    print(f'Name:     {name}')
    print(f'Version:  {version}')
else:
    raise ValueError(f'Invalid identifier {example}')

출력:

Name:     hello
Version:  0.0.1

아무도 앞을 내다보고 뒤돌아보는 것을 추천하지 않은 특별한 이유가 있나요?도 똑같은 일을 온 거야(?<=<title>).+(?=<\/title>)잘 동작합니다.괄호 사이의 내용만 일치하므로 그룹 전체를 수행할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/1327369/extract-part-of-a-regex-match

반응형