>source

로그에서 사전으로 데이터를 추출하려고합니다. 로그의 첫 번째 줄은 다음과 같습니다.

146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622

IP를 사전에 추출했지만 사용자 이름 (하이픈 뒤)을 얻으려고 할 때 다음과 같은 출력이 표시됩니다.

{'host': '146.204.224.152', 'user_name': ' '}

이것은 내가 사용하는 코드입니다.

for item in re.finditer("(?P<host>[0-9]+(?:\.[0-9]+){3})(P<user_name>(?<=- )*\s)", logdata):
print(item.groupdict())

나는 정규식에 대한 멍청이입니다. 내가 뭘 잘못하고 있는지에 대한 조언이 있습니까?

내가 원하는 출력은 다음과 같아야합니다.

{'host': '146.204.224.152', 'user_name': 'feest6811'}


  • 답변 # 1

    우선 오타가 있습니다. (P<user_name> 반드시 (?P<user_name> .

    정규식 엔진은 문자열을 왼쪽에서 오른쪽으로 구문 분석합니다 (적어도 기본적으로 오른쪽에서 왼쪽 구문 분석을 지원하는 정규식 라이브러리가 많지 않음). 문자열은 문자별로 읽히고 이러한 문자를 패턴과 일치 시키려고합니다. 소비하는 하위 패턴 (예 : 정규식 인덱스를 발전시키는 것, 즉 비 둘러보기) 사이의 문자열 부분을 건너 뛸 수 없습니다. 그래서 (?<=- )* 그 뒤에 긍정적 인 모습입니다필요하다- 그리고 될 공간바로현재 위치의 왼쪽에0 회 이상때문에 * 그 후에. 이 * 수량자는 아무것도 요구하지 않기 때문에 여기에서 lookbehind를 사용하는 전체 아이디어를 무의미하게 만듭니다. 따라서이 모든 작업은 다음과 같이 공백을 캡처합니다. \s .

    필요한 것은바싹 여위다날짜와 사용자 사이의 부분, 예를 들어 \s+-\s+ 또는 \s+\S+\s+ :

    (?P<host>[0-9]+(?:\.[0-9]+){3})\s+-\s+(?P<user_name>\S+)
    
    

    정규식 데모를 참조하십시오.

    그만큼 \s+-\s+ 일치 - 하나 이상의 공백으로 묶여 있고 \s+\S+\s+ 하나 이상의 공백으로 묶인 하나 이상의 공백이 아닌 문자와 일치합니다.

  • 이전 dart - 실룩 거리다 자식 캔버스 그림을 기반으로 부모의 높이 설정
  • 다음 elasticsearch - 구별, 정렬, 페이지 매김, 필터링을 사용하여 문서를 검색하려면 어떻게해야합니까?