[완료][정규식] 로그나 특정 문자열을 파싱하고 싶습니다.

bellfive2000의 이미지

자막이나 로그 파일을 특정 패턴으로 파싱하고 싶을 때가 많습니다.
여러 정규식 tutorial등을 보고 있으나 특정 부분에서 막히는 부분이 있어 질문 올립니다.

예를 들면 아래와 같은 문자열이 있을 때

00:00:01.720 ~ 00:00:03.410  Jindai Tokyo Municipal High School
1)                2)                    3)

1) 시작 시간
2) 끝 시간
3) 문자열

이렇게 3개의 문자열로 얻기를 원합니다.

그래서 저같은 경우는 자바로 짜고 있긴 하지만.. 일단
 (\w+\:\w+\:\w+\.\w+) \~ (\w+\:\w+\:\w+\.\w+)
와 같이 처리해보면

00:00:01.720 ~ 00:00:03.410
와 같이 얻어 오는 것 까지는 확인 했습니다.

해당 문자열을 파싱해서 얻어오는 정규식에 대한 힌트 좀 얻고 싶습니다.
https://regexper.com/ 같은 곳에서 확인하면서 진행하는데 좀처럼 진전이 없어서 문의 드립니다.

김정균의 이미지

http://kr.php.net/manual/en/pcre.pattern.php
http://stackoverflow.com/questions/1448164/what-support-is-there-for-pcre-perl-compatible-regular-expressions-in-common-l

문서 참고 하세요. 두번째 링크는 java로 테스트를 한다고 하셔서, java에서 PCRE style의 정규식에 관한 내용이라 추가했습니다. 첫번째 문서는 PHP 문서인데 PCRE 정규식 문법을 공부하기에 잘 분류가 되어 추천해 드립니다.

아래는 원하시는 정규식 예제이고요. :-)

PCRE regex:

# match group $1, $2, $3
 
^(\d{2}:\d{2}:\d{2}\.\d+)\s+~\s+(\d{2}:\d{2}:\d{2}\.\d+)\s+(.+)$

조금 더 축약 하면

# match group $1, $3, $5
 
^((\d{2}:){2}\d{2}\.\d+)\s*~\s*((\d{2}:){2}\d{2}\.\d+)\s+(.+)$

grep regex:

# match group $1, $3, $5
 
'^\(\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\.[0-9]\+\)\s\+~\s\+\(\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\.[0-9]\+\)\s\+\(.\+\)$

요즘의 grep의 경우에는 -p 옵션으로 pcre style 정규식을 사용할 수 있습니다.

 의 이미지

정규표현식 짜는 방법이야 오만가지 있습니다만, 가장 큰 고려사항은 역시나 타겟 텍스트가 얼마나 Regular하느냐이지요.

이미 김정균님께서 다 풀어주셨는데, 사실 ERE에서 \d는 없지만 대신 [[:digit:]]가 있습니다. 물론 이 경우에는 [0-9]가 더 짧고 간결하기는 합니다만.

([[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\.[[:digit:]]{3})\s*~\s*([[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\.[[:digit:]]{3})\s*(.*)
bellfive2000의 이미지

답변 달아주신 두분 정말 감사합니다. ^^
적어주신 문서도 정독하겠습니다.

bellfive2000의 이미지

모두 잘 동작하고 있어서 좋아했었는데요.
중간에 개행문자 \n 이 들어간 문자열이 존재하네요
"00:00:18.070 ~ 00:00:20.510 And it's all the work of[\n]that student, Sagara Sousuke!"

\n이 들어가버리면 (.+)로 걸러주지 못하는 것 같습니다.
자바에서 테스트를 해서 그런 것 같기도 합니다.

http://www.freeformatter.com/regex-tester.html
여기에선 위에 올려주신 정규식으로 잘 매칭이 되는걸로 봐선 그런 것 같습니다.
자바는 개행문자를 정규식으로 처리할 때 더 확인해야 할 사항이 있는지 궁금합니다.

김정균의 이미지

이런 경우라면, 정규식을 사용하기 전에 normalizing을 먼저 하시는 것이 맞습니다. 물론 이 normalizing 역시 정규식으로 처리할 수도 있겠죠 :-)

 의 이미지

역사적인 이유로 정규표현식은 찾으려는 패턴이 여러 라인에 걸쳐 있을 때 좀 사용하기 번거로워집니다.

언제까지고 과거에 묶여있는 건 아닌 만큼 어떻게 할 방법이야 있습니다만, 잘 알고 써야만 하죠.
예컨대 파이썬 2.7 re 모듈에서는 re.MULTILINE을 지정해 주어야만 ^$이 각각 라인의 시작과 끝에 매칭되고, re.DOTALL을 지정해야만 .이 개행 문자와도 매칭됩니다.

자바의 정규표현식에도 비슷한 옵션들이 있을 텐데, 저는 자바는 잘 모릅니다. 레퍼런스를 찾아보면 나오겠죠. 하지만 사실 그런 옵션이 중요한 문제인 게 아닙니다.

앞서 드린 정규표현식은 대체로 개행 문자를 만나면 패턴이 끝난다는 가정 하에서 설계되었거든요. 근데 패턴이 개행 문자 뒤로도 이어진다면 일단 이 가정이 무너지고 모든 게 카오스에 빠지게 됩니다. 옵션만 바꿔서 쓴다고 이게 자동으로 해결되는 게 아니죠. 그러면 아마 패턴 하나가 전체 텍스트를 다 커버할걸요? .*.+가 greedy하게 동작할 텐데, 그걸 막을 수 있는 문자가 아무것도 없으니까요.

이 경우를 해결하려면 최소한의 가정을 다시 정립해서 정규표현식을 새로 설계해야 됩니다. 이건 간단한 문제는 아닙니다. 그래서 제가 입력 텍스트가 얼마나 Regular한지가 중요하다고 말씀드렸지요.

김정균의 이미지

PCRE에서는 s modifier로 .(dot)에 개행을 포함 시킬 수 있습니다. multilime은 m modifer를 이용하면 됩니다. 자바는 모르겠습니다. :-)

/.+/s
bellfive2000의 이미지

김정균님이 말씀해주신 대로 얻은 값을 replace등으로 변경하는 방법으로 처리는 했습니다.

개행 문자는 정말로 특수한 경우니 언급해주신대로 하는 것이 패턴을 무너뜨리지 않겠네요^^
많이 배웠습니다.
감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.