"이제 두 가지 문제가 있습니다"란 무엇입니까?


200

Jamie Zawinski 의 인기 인용문 이 있습니다 .

어떤 사람들은 문제에 직면했을 때 "정규 표현을 사용할 것입니다."라고 생각합니다. 이제 두 가지 문제가 있습니다.

이 인용문은 어떻게 이해되어야합니까?


46
두 번째 문제는 정규식을 사용하고 있지만 여전히 첫 번째 문제를 해결하지 못했기 때문에 두 가지 문제입니다.
Ampt

24
@Euphoric-실제로 좋은 코드 짧지 만 암호 적 으로 간결하지 않습니다.
Steve314

24
@IQAndreas : 반 유머적인 것 같아요. 주의해야 할 점은 조심하지 않으면 정규 표현식을 사용하면 상황이 나아지는 것보다 나빠질 수 있다는 것입니다.
FrustratedWithFormsDesigner

145
어떤 사람들은 무언가를 설명하려고 할 때 "제이미 자윈 스키 (Jamie Zawinski)의 인용문을 사용할 것입니다."라고 생각합니다. 이제 그들은 설명해야 할 두 가지가 있습니다.
detly

답변:


220

일부 프로그래밍 기술은 일반적으로 프로그래머 (가 잘 이해되지 않습니다 정규 표현식 , 부동 소수점 , , AWK , IOC의 ... ).

이들은 올바른 문제를 해결하기위한 놀랍도록 강력한 도구가 될 수 있습니다. 정규 표현식은 특히 정규 언어를 일치시키는 데 매우 유용합니다. 그리고 문제의 요점이 있습니다 : 일반 언어를 묘사하는 방법을 아는 사람은 거의 없습니다 (재미있는 기호를 사용하는 컴퓨터 과학 이론 / 언어학의 일부입니다 -Chomsky 계층 에서 읽을 수 있습니다 ).

이러한 것들을 다룰 때, 잘못 사용하면 실제로 원래 문제를 해결했을 가능성이 없습니다. 정규 표현식을 사용하여 HTML (매우 흔하게 발생하는) 과 일치 하면 가장자리 빠질 수 있습니다. 그리고 지금, 당신은 여전히 ​​해결하지 못한 원래 문제와 잘못된 솔루션을 사용하여 그 주위에 떠있는 또 다른 미묘한 버그가 있습니다.

이것은 정규 표현식을 사용해서는 안된다는 것이 아니라, 그들이 해결할 수있는 문제들을 이해하고 그것을 해결할 수없고 신중하게 사용할 수 있도록 노력해야한다는 것입니다.

소프트웨어 유지 관리의 핵심은 유지 관리 가능한 코드를 작성하는 것입니다. 정규식을 사용하면 그 목표에 맞설 수 있습니다. 정규 표현식으로 작업 할 때 특수 도메인 특정 언어로 미니 컴퓨터 (특히 비 결정적 유한 상태 자동 장치 )를 작성했습니다. 이 언어로 'Hello world'를 작성하는 것은 쉽지만 기본적인 신뢰를 얻지 만, 식별하고 수정하기 어려운 추가 버그를 작성하지 않기 위해 일반 언어를 이해함으로써 더 나아가 야합니다. 정규 표현식이있는 프로그램의 일부는 아닙니다).

이제 새로운 문제가 생겼습니다. 정규식 도구를 사용하여 문제를 해결할 때 (부적절한 경우), 두 가지 버그가 있습니다. 두 가지 버그가 있습니다. 두 가지 버그는 다른 추상화 계층에 숨겨져 있기 때문에 찾기가 더 어렵습니다.


8
나는 펄 자체가 프로그래머가 잘 이해하지 못하는 기술 목록에 속하는지 확신하지 못한다.;)
crad

21
@ perl에 대해서도 더 많은 것을 말하고 있습니다. 난 여전히 랜드 토크에서 부동 소수점 하나를 좋아한다 : "이제 2.00000152 문제가 있습니다"

56
@crad 어떤 사람들은 문제에 직면했을 때 "나는 펄을 사용할 것이다."라고 생각합니다. 이제 $ (^ @ # % () ^ %) (#) 문제가 있습니다.
Michael Hampton

4
아무것도, 기존의 정규식 대 PCRE의 추가 전력이 더 유혹 솔루션을 만드는 경우 @Jens 한을 유지하기가 더 어렵습니다. PCRE와 일치하는 유한 오토마타는 유한 오토마타를 확장하여 Perl 호환 정규 표현식을 효율적으로 일치 시키는 방법과 그 사소한 것이 아닙니다. 최소한 전통적인 정규 표현식을 사용 하면 필요한 개념을 이해하면 너무 많은 어려움 없이 머리를 감쌀 수 있습니다 .

6
당신은 좋은 지적을합니다. 정규 표현식은 사실상 두 번째로 사소한 언어입니다. 원래 프로그래머가 주 언어에 능숙하고 정규식의 풍미를 사용하더라도 "두 번째 언어"를 추가하면 관리자가 두 가지 모두를 알 확률이 낮아집니다. 정규 표현식의 가독성은 종종 "호스트"언어보다 낮습니다.
JS.

95

정규 표현식, 특히 사소한 표현은 코딩, 이해 및 유지 관리가 어려울 수 있습니다. 질문자가 질문에 [regex]대한 답변이 정규식이라고 가정하고 그 뒤에 붙어 있는 스택 오버플로 태그의 질문 수만 살펴보십시오 . 많은 경우에 문제는 다른 방식으로 해결 될 수 있습니다.

이것은 정규식을 사용하기로 결정하면 이제 두 가지 문제가 있음을 의미합니다.

  1. 해결하려는 원래 문제.
  2. 정규식의 지원.

기본적으로, 나는 당신이 문제를 해결할 다른 방법이 없다면 정규식 만 사용해야한다는 것을 의미한다고 생각합니다. 다른 솔루션은 코딩, 유지 관리 및 지원이 더 쉬울 것입니다. 속도가 느리거나 효율이 떨어질 수 있지만 유지 관리가 쉬워지지 않으면 지원 및 지원이 가장 중요합니다.


27
더 나쁜 것은 HTML처럼 사람들이 할 수없는 것들을 파싱하기 위해 사람들을 속이도록 속일만큼 강력하다. "HTML 구문 분석 방법"에 대한 SO에 대한 수많은 질문을 참조하십시오.
Frank Shearar

6
어떤 상황에서는 정규 표현식이 훌륭합니다. 다른 많은 경우에는 그렇게 많지 않습니다. 다른 한편으로 그것은 끔찍한 절망의 구덩이입니다. 누군가가 처음으로 배우고 어디서나 응용 프로그램을 볼 때 문제가 종종 발생합니다. 또 다른 유명한 말 : "당신이 가진 유일한 도구가 망치 일 때 모든 것이 못처럼 보입니다."
Todd Williamson

3
이는 SO [c #] 태그의 질문 수로 이해하기 가장 어려운 프로그래밍 언어라는 것을 의미합니까?

2
문자열 메서드에 대한 긴 일련의 호출보다 복잡한 정규식을 보는 것이 좋습니다. OTOH, 나는 복잡한 언어를 파싱하기 위해 정규 표현식이 잘못 사용되는 것을 정말로 싫어합니다.
케빈 클라인

5
"기본적으로, 그는 문제를 해결할 다른 방법이 없다면 정규식 만 사용해야한다는 것을 의미한다고 생각합니다. 다른 솔루션은 코딩, 유지 관리 및 지원이 더 쉬울 것입니다." -심각하게 동의하지 않습니다. 정규 표현식은 훌륭한 도구이므로 한계를 알아야합니다. 많은 작업을 정규식으로 더 우아하게 코딩 할 수 있습니다. (그러나, 단지 예를 들어, HTML을 파싱하기 위해 그것들을 사용해서는 안됩니다)
Karoly Horvath

69

그것은 진실의 곡물에도 불구하고 주로 뺨에 뺨 농담입니다.

정규식이 잘 맞는 몇 가지 작업이 있습니다. 한 번은 500 줄의 수동으로 작성된 재귀 강하 파서 코드를 하나의 정규 표현식으로 바꾸어 완전히 디버그하는 데 약 10 분이 걸렸습니다. 사람들은 정규 표현식을 이해하고 디버깅하기가 어렵지만 적절하게 적용되는 규칙은 손으로 설계된 거대한 파서만큼 디버그하기가 쉽지 않다고 말합니다. 내 예에서는 정규식이 아닌 솔루션의 모든 주요 사례를 디버깅하는 데 2 ​​주가 걸렸습니다.

그러나 벤 아저씨를 다음과 같이 표현하면 :

표현력이 뛰어나면 큰 책임이 따릅니다.

다시 말해, 정규 표현식은 언어에 표현력을 더해 주지만, 주어진 작업에 대해 가장 읽기 쉬운 표현 모드를 선택하도록 프로그래머에게 더 많은 책임을 부여합니다.

어떤 것은 처음에는 정규 표현식에 좋은 작업처럼 보이지만 그렇지 않습니다. 예를 들어 HTML과 같이 중첩 된 토큰이있는 모든 것이 있습니다. 때로는 더 간단한 방법이 더 명확 할 때 사람들이 정규식을 사용합니다. 예를 들어, string.endsWith("ing")동등한 정규 표현식보다 이해하기 쉽습니다. 때때로 사람들은 큰 문제를 하나의 정규 표현식으로 만들려고하는데, 조각으로 나누는 것이 더 적절합니다. 때로는 사람들이 적절한 추상화를 작성하지 못하고 동일한 작업을 수행하는 잘 알려진 함수를 작성하는 대신 정규식을 반복해서 반복합니다 (아마도 정규식으로 내부 구현).

어떤 이유로 든 정규 표현식은 단일 책임 및 DRY와 같은 일반적인 소프트웨어 엔지니어링 원칙에 대한 사각 지대를 만드는 이상한 경향이 있습니다. 그렇기 때문에 자신을 사랑하는 사람들조차도 때때로 문제를 발견하는 것입니다.


10
벤 아저씨도 "완벽한 결과"라고 말하지 않았습니까? 어쩌면 사람들이 정규 표현식에 만족하게 될 수도 있습니다.
Andrzej Doyle

4
경험이 부족한 개발자를 여행하는 HTML과 관련된 정규 표현식의 문제는 HTML에 컨텍스트가없는 문법이 있고 규칙이 아니라는 것입니다. 정규 표현식은 간단한 HTML (또는 XML) 구문 분석 (예 : 명명 된 앵커 태그에서 URL을 가져 오는 데)에 사용할 수 있지만 복잡한 것에 적합하지 않습니다. 이를 위해서는 DOM 구문 분석이 더 적합합니다. 관련 독서 : Chomsky hierarchy .

53

Jeff Atwood는이 글을 인용 한 블로그 게시물에서 다른 해석을 제공합니다. 정규식 : 이제 두 가지 문제가 있습니다 ( 링크에 대한 행복감 )

1997 년 실의 Jamie 게시물의 전체 내용을 분석하면 다음과 같은 결과를 얻을 수 있습니다.

Perl의 본질은 다른 모든 기술을 거의 배제하기 위해 정규 표현식을 사용하도록 권장합니다. 그들은 A 지점에서 B 지점으로 갈 수있는 가장 "명백한"(적어도 더 잘 모르는 사람들에게) 멀고 멀리 떨어져 있습니다.

첫 번째 인용문은 너무 어리석어 서 심각하게 받아 들일 수 없습니다. 그러나 이것은 전적으로 동의합니다. 제이미가하려고하는 요점은 다음과 같습니다. 정규 표현식 자체가 악한 것이 아니라 정규 표현식을 과도하게 사용하는 것은 악한 것입니다.

당신이 경우에도 않는 완전히 정규 표현식을 이해, 당신은으로 실행 황금 망치 가 쉽고 (참조 일반 코드와 같은 일을하는 것이 더 명확했을 때 정규 표현식에 문제를 해결하기 위해 노력하고, 문제 CodingHorror : 정규식 사용 대 정규식 학대 ).

인용문의 맥락을 살펴보고 Atwood보다 자세한 내용을 다루는 또 다른 블로그 게시물이 있습니다. Jeffrey Friedl의 블로그 : 유명한 "지금 두 가지 문제가 있습니다"인용문의 출처


3
이것은 내 생각에 문맥을 추가하기 때문에 가장 좋은 대답입니다. jwz의 정규 표현식에 대한 비판은 Perl에 관한 것입니다.
Evicatos

3
@Evicatos 다른 블로그 게시물에서 같은 1997 스레드에 대해 더 많은 연구가 수행되었습니다. regex.info/blog/2006-09-15/247
IQAndreas

30

이 인용문에는 몇 가지 일이 있습니다.

  1. 인용문 은 이전 농담을 다시 언급 한 것입니다.

    문제가 생길 때마다 "AWK를 사용하자"고 말하는 사람들이 있습니다. 이제 두 가지 문제가 있습니다. — 디 틸 브룩

    그것은 농담과 실제 발굴이지만 정규식을 다른 나쁜 솔루션과 연결하여 나쁜 솔루션으로 강조하는 방법이기도합니다. 그것은 중대 하, 하, 심각한 순간.

  2. 이 인용문은 의도적으로 해석에 개방되어 있습니다. 그 의미는 간단합니다. 정규 표현식을 사용한다는 아이디어 만 발표해도 문제가 해결되지 않았습니다. 또한 사용하는 언어와 다른 규칙을 가진 언어를 추가하여 코드의인지 복잡성을 증가 시켰습니다.

  3. 농담으로 재미 있기는하지만 정규식이 아닌 솔루션의 복잡성과 정규식 솔루션의 복잡성과 정규식 포함의 추가 복잡성을 비교해야합니다. 정규식을 추가하는 데 드는 추가 비용에도 불구하고 정규식 문제를 해결하는 것이 좋습니다.


21

정규 표현식은 현재 설정되어 있지 않거나 형식화되지 않은 다른 모든 내용을 유지하고 있습니다.이 문서에서는 읽기 어려운 경우가 있지만, 불행히도 형식화를 허용하지 않으며 사람들이 당신이 할 수 있다는 사실을 모르기 때문에 불행히도 그 결과물을 읽을 수 없습니다.

(정규 표현식은 다른 형식화되지 않은 콘텐츠보다 읽거나 유지하기가 더 나쁘지 않습니다. 실제로 정규 표현식 이이 텍스트보다 읽기 쉽습니다. 그러나 불행히도 일부 구현에서는 형식 지정 및 일반 사용자를 허용하지 않기 때문에 평판이 좋지 않습니다. 할 수 있다는 것을 몰라요.)


다음은 간단한 예입니다.

^(?:[^,]*+,){21}[^,]*+$


어쨌든 읽거나 유지하기가 어렵지는 않지만 다음과 같이하면 더 쉽습니다.

(?x)    # enables comments, so this whole block can be used in a regex.
^       # start of string

(?:     # start non-capturing group
  [^,]*+  # as many non-commas as possible, but none required
  ,       # a comma
)       # end non-capturing group
{21}    # 21 of previous entity (i.e. the group)

[^,]*+  # as many non-commas as possible, but none required

$       # end of string

그것은 약간의 오버 윗 예제 (설명은 논평 $과 유사합니다 i++)이지만 분명히 읽고 이해하고 유지하는 데 아무런 문제가 없어야합니다.


정규 표현식이 적합한시기와 나쁜 생각 일 때 분명한 한, 아무 문제가 없으며 대부분 JWZ 견적이 실제로 적용되지 않습니다.


1
물론, 나는 정규 표현식의 장점에 대한 토론을 찾고 있지 않으며,이 토론이 그렇게되는 것을보고 싶지 않습니다. 나는 그가 무엇을 얻고 있는지 이해하려고 노력하고 있습니다.
Paul Biggar

1
그런 다음 livibetter의 의견 링크에 알아야 할 내용이 나와 있습니다. 이 응답은 정규 표현식이 모호해질 필요가 없으므로 인용문은 말이 안됩니다.
Peter Boughton

8
사용의 요점은 무엇입니까 *+? 그것은 (기능적으로) 다른 것과 어떻게 다른 *가요?
Timwi

1
당신이 말하는 것은 사실 일지 모르지만,이 특정한 질문에 대한 답은 아닙니다. 당신의 대답은 "제 말은 일반적으로 사실이 아니라고 생각합니다"로 요약됩니다. 문제는 그것이 사실인지 아닌지에 관한 것이 아니라 견적의 의미에 관한 것입니다.
Bryan Oakley

2
*+이 경우 말 그대로 의미가 없습니다 . 모든 것은 고정되어 있으며 최대 22 개까지 셀 수있는 자동 장치로 단일 패스로 일치시킬 수 있습니다. 쉼표가 아닌 세트의 올바른 수정자는 평범 *합니다. (또한 여기에서 욕심쟁이와 욕심없는 매칭 알고리즘 사이에는 차이가 없어야합니다. 매우 간단한 경우입니다.)
Donal Fellows

14

ChrisF의 답변 외에도 정규 표현식은 "코딩, 이해 및 유지 관리가 어렵다"는 단점이 있습니다. HTML과 같이 할 수없는 것을 구문 분석하기 위해 사람들을 속이려고 할 정도로 강력합니다. "HTML 구문 분석 방법"에 대한 SO에 대한 수많은 질문을 참조하십시오. 예를 들어, 가장 서사시 대답 SO의 모두!


14

정규식은 매우 강력하지만 작고 큰 문제가 있습니다. 그들은 쓰기가 어렵고 읽기가 거의 불가능합니다.

가장 좋은 경우 정규식을 사용하면 문제가 해결되므로 복잡한 코드의 유지 관리 문제 만 발생합니다. 정규 표현식을 제대로 얻지 못하면 원래 문제와 읽을 수없는 코드 문제가 있습니다.

때로는 정규식을 쓰기 전용 코드라고합니다. 수정이 필요한 정규 표현식에 직면하면 표현식을 이해하려고 시도하는 것보다 처음부터 시작하는 것이 더 빠릅니다.


1
실제 문제는 정규 표현식이 파서를 구현할 수 없다는 것입니다. 예를 들어 파서가 현재 얼마나 깊이 중첩되어 있는지 계산할 수 없기 때문입니다.

4
@ Thorbjørn Ravn Andersen : 문제보다 한계가 있습니다. 정규 표현식을 사용하려고하면 문제가되며 정규 표현식에는 문제가 없으며 방법 선택에 문제가 있습니다.
Guffa

1
당신은 어휘 분석기 (대부분의 언어에서)에 대해 RE를 잘 사용할 수 있지만 토큰 스트림을 구문 분석 트리로 조립하는 것 (즉, 구문 분석 )은 공식적으로 그 이상입니다.
Donal Fellows

10

문제는 정규식이 복잡한 짐승이며 정규식을 완벽하게 사용하는 경우에만 문제를 해결한다는 것입니다. 그렇지 않으면 원래 문제 정규식이라는 두 가지 문제가 발생합니다 .

당신은 그것이 100 줄의 코드 작업을 할 수 있다고 주장하지만 100 줄의 명확하고 간결한 코드가 한 줄의 정규 표현식보다 낫다는 주장을 할 수도 있습니다.

이에 대한 증거가 필요한 경우 :이 SO Classic을 확인 하거나 SO 정규식 태그를 통해 간단하게 빗질 할 수 있습니다.


8
첫 문장의 주장은 사실이 아닙니다. 정규식은 특별히 복잡하지 않으며 다른 도구와 마찬가지로 문제를 해결하기 위해 완벽하게 알아야합니다. 그것은 단지 FUD입니다. 두 번째 단락은 말도 안됩니다. 물론 논쟁을 할 수 있습니다. 그러나 좋은 것은 아닙니다.
Konrad Rudolph

1
@KonradRudolph 많은 정규 표현식 생성 및 유효성 검사 도구가 있다는 사실은 정규 표현식 복잡한 메커니즘 임을 보여줍니다 . 사람이 읽을 수 없으며 (설계 상) 정규식을 사용하는 코드를 수정하거나 작성하는 사람에게 흐름이 완전히 변경 될 수 있습니다. 두 번째 부분에 관해서는 P.SE에 대한 방대한 지식 그룹과 "디버깅 코드는 작성하는 것보다 두 배 어렵다"는 말이 분명하다고 생각합니다. 정의에 따르면, 그것을 디버깅하기에 충분히 똑똑하지 않다 "
Ampt

2
그것은 적절한 논쟁이 아닙니다. 예, 정규 표현식이 복잡합니다. 그러나 다른 프로그래밍 언어들도 마찬가지입니다. 정규 표현식은 다른 대부분의 언어보다 훨씬 복잡하며 정규 표현식에 존재하는 도구는 다른 언어의 개발 도구로 인해 난쟁이입니다 (FWIW 정규 표현식으로 광범위하게 작업하고 그런 도구를 사용한 적이 없습니다 ...). 복잡한 정규 표현식조차도 정규 표현식이 아닌 구문 분석 코드보다 간단 하다는 것은 단순한 사실입니다 .
Konrad Rudolph

@KonradRudolph 우리는 그 단어의 정의에 대한 근본적인 의견 불일치가 있다고 생각합니다. 정규식이 더 효율적 이거나 더 강력 할 수 있다고 말씀 드리지만, 정규식을 생각할 때 누군가의 마음에 오는 단어가 단순 하다고 생각하지 않습니다 .
Ampt

어쩌면 우리가하지만 내 정의는 실천이다 : 나는 유지하기 쉽고, 이해하기 쉬운 말은 간단 가지고, 숨겨진 버그 등의 낮은 숫자는 물론 복잡한 정규식 먼저 눈에 것 없는 매우 이해 본다. 그러나 정규식이 아닌 동등한 코드 조각에 대해서도 마찬가지 입니다. 정규식이 간단하다고 말한 적이 없습니다. 나는 그들이 더 간단 하다고 말하고 있습니다 – 나는 비교하고 있습니다. 중요합니다.
Konrad Rudolph

7

의미는 두 부분으로 구성됩니다.

  • 첫째, 원래 문제를 해결하지 못했습니다.
    이것은 정규 표현식이 종종 일반적인 문제에 대한 불완전한 솔루션 을 제공한다는 사실을 의미합니다 .
  • 둘째, 이제 선택한 솔루션과 관련된 추가 난이도가 추가되었습니다.
    정규 표현식의 경우 추가 난이도는 복잡성, 유지 관리 가능성 또는 정규 표현식을 해결하지 못했던 문제에 맞추는 데 따른 추가 어려움을 의미합니다.

7

2014 년에 요청하면 오늘날의 상황과 비교하여 1997 년의 상황에서 프로그래밍 언어 이데올로기에 초점을 맞추는 것이 흥미로울 것입니다. 여기서는이 토론에 참여하지 않겠지 만 Perl과 Perl 자체에 대한 의견은 크게 바뀌 었습니다.

그러나 2013 년 상황 ( de l' eau a coulé sous les ponts depuis)을 유지하려면 Jamie Zawinski의 직접 인용 인 유명한 XKCD 만화를 사용하여 따옴표로 재현하는 데 중점을 두는 것이 좋습니다 .

정규 표현식, Perl 및 문제에 관한 XKCD의 만화

먼저 나는 그것이 Zawinski 인용에 대한 참조했기 때문에이 만화를 이해하는 문제가 있었다 제이 - Z의 노래 가사의 견적, 그리고 GNU의의 참조 program --help -z플래그 2를 내가 그것을 이해하는 것이 너무 많은 문화를했다, 그래서.

나는 그것이 재미 있다는 것을 알고, 느끼고 있었지만, 왜 그런지 몰랐습니다. 사람들은 종종 Perl과 정규 표현식에 대해 농담을합니다. 특히 가장 프로그래밍 언어가 아니기 때문에 왜 재미 있어야하는지 모르겠습니다. 아마도 Perl 상인들이 바보 같은 일을 하기 때문일 입니다.

따라서 초기 인용문은 실제 도구 (고통?)를 기반으로 한 비꼬는 농담 인 것처럼 보입니다. 해머가 메이슨을 해칠 수있는 것처럼, 개발자가 그가 다칠 수있는 도구 (뇌, 감정)가 아닌 도구로 프로그래밍하는 것은 메이슨을 해칠 수 있습니다. 때로는 큰 논쟁은 대한 도구가 발생 최선이지만의 문제의 원인은 거의 쓸모의 취향 이나 프로그래밍 팀의 맛 , 문화 또는 경제적 인 이유. 이것에 대한 또 다른 훌륭한 XKCD 만화 :

프로그래밍 도구 토론에 대한 XKCD의 만화

나는 사람들이 정규 표현식에 대해 고통을 느끼는 것을 이해할 수 있으며 다른 도구가 정규 표현식 용으로 더 적합하다고 생각합니다. @ karl-bielefeldt가 귀하의 질문 에 큰 표현력으로 대답함에 따라 큰 책임이 따르고 정규 표현식 이 특히 염려됩니다. 개발자가 정규 표현식을 처리하는 방법을 신경 쓰지 않으면 나중에 코드를 유지 관리하는 사람들에게 고통을 줄 것입니다.

나는 Damian Conw ay의 Perl Best Practices (2005 년 책) 전형적인 예를 보여주는 인용구로 인용 된 재연에 대한이 답변으로 마무리 할 것 입니다.

그는 다음 과 같은 패턴작성 한다고 설명합니다 .

m{'[^\\']*(?:\\.[^\\']*)*'}

... 다음 과 같은 프로그램을 작성하는 것보다 더 이상 용납되지 않습니다 .

sub'x{local$_=pop;sub'_{$_>=$_[0
]?$_[1]:$"}_(1,'*')._(5,'-')._(4
,'*').$/._(6,'|').($_>9?'X':$_>8
?'/':$")._(8,'|').$/._(2,'*')._(
7,'-')._(3,'*').$/}print$/x($=).
x(10)x(++$x/10).x($x%10)while<>;

그러나이 수 다시 작성 그것의, 여전히 꽤 아니지만, 적어도 지금은 생존입니다.

# Match a single-quoted string efficiently...
m{ '            # an opening single quote
    [^\\']*     # any non-special chars (i.e., not backslash or single quote)
    (?:         # then all of...`
    \\ .        # any explicitly backslashed char
    [^\\']*     #    followed by any non-special chars
    )*          # ...repeated zero or more times
    '           # a closing single quote
}x

이러한 종류의 직사각형 코드 명확하고 유지 보수 가능하며 읽을 수있는 형식으로 형식화 할 수있는 정규식이 아닌 두 번째 문제입니다.


2
/* Multiply the first 10 values in an array by 2. */ for (int i = 0 /* the loop counter */; i < 10 /* continue while it is less than 10 */; ++i /* and increment it by 1 in each iteration */) { array[i] *= 2; /* double the i-th element in the array */ }
5gon12eder

6

컴퓨터 과학에서 배워야 할 것이 있다면 Chomsky 계층 구조 입니다. 정규 표현식의 모든 문제는 문맥이없는 문법을 구문 분석하려는 시도에서 비롯된 것입니다. CFG에서 중첩 수준에 제한을 적용하거나 제한을 적용 할 수 있다고 생각하면 길고 복잡한 정규 표현식을 얻을 수 있습니다.


1
예! CS 배경의 일부가없는 정규 표현식을 배우는 사람들은 정규 표현식이 수학적으로 할 수없는 일이 있다는 것을 항상 이해하지는 않습니다 .
벤 자도

5

정규식은 전체 구문 분석보다 토큰 화에 더 적합합니다.

그러나 프로그래머가 구문 분석해야 할 놀랍게도 많은 것들이 일반 언어로 구문 분석 가능합니다 (또는 일반 언어로 거의 구문 분석 가능하며 조금 더 코드를 작성하는 경우 ...).

따라서 "aha, 텍스트를 따로 골라야합니다. 정규 표현식을 사용하겠습니다"라는 습관이 있다면 푸시 다운 오토 마톤, CFG 파서 또는 훨씬 더 강력한 문법. 그것은 보통 눈물로 끝납니다.

그래서 나는 인용문이 너무 많은 정규 표현식을 슬프게 생각하지는 않지만 그것들의 사용 (그리고 잘 사용되면 실제로 매우 유용합니다)이지만 정규 표현식에 대한 과도한 의존 (또는 특히 비판적 선택) .


3

jwz는 그 인용구로 로커를 벗어났습니다. 정규 표현식은 다른 언어 기능과 다르지 않습니다. 쉽게 조일 수 있고, 우아하게 사용하기 어렵고, 강력하고, 때로는 부적절하며, 자주 문서화되고, 종종 유용합니다.

부동 소수점 산술, 클로저, 객체 지향, 비동기 I / O 또는 기타 이름을 지정할 수 있습니다. 당신이 무엇을하고 있는지 모른다면, 프로그래밍 언어는 당신을 슬프게 할 수 있습니다.

정규식을 읽기 어렵다고 생각되면 해당 패턴을 사용하기위한 동등한 구문 분석기 구현을 읽으십시오. 정규 표현식은 전체 파서보다 작기 때문에 종종 승리합니다. 대부분의 언어에서는 속도도 빠릅니다.

자체 홍보 블로거는 자격이없는 진술을하기 때문에 정규 표현식 (또는 다른 언어 기능)을 사용하지 마십시오. 직접 시도해보고 어떤 것이 효과가 있는지보십시오.


1
FWIW, 부동 소수점 산술은 RE 보다 까다 롭지 만 더 단순 해 보입니다. 조심해! (적어도 까다로운 RE는 위험 해 보이는 경향이 있습니다.)
Donal Fellows

3

이에 대한 내가 가장 좋아하는 심층 답변은 유명한 Rob Pike가 내부 Google 코드 주석에서 재현 한 블로그 게시물에서 제공합니다 . and.html

요약은 그것이 나쁘지 는 않지만, 특히 일부 입력을 분석하고 구문 분석 할 때 반드시 적합하지 않은 작업에 자주 사용된다는 것입니다.

정규식은 쓰기가 어렵고 쓰기가 어렵고 다른 기술에 비해 비쌀 수 있습니다. 반면 Lexers는 정확하게 작성하기가 쉽고 (간결하지는 않지만) 테스트하기가 매우 쉽습니다. 영숫자 식별자를 찾아보십시오. 정규 표현식 ( "[a-ZA-Z _] [a-ZA-Z_0-9] *"와 같은 것)을 작성하는 것은 그리 어렵지 않지만 간단한 루프로 작성하는 것은 그리 어렵지 않습니다. 그러나 루프의 성능은 훨씬 높을 것이며 커버 아래의 코드는 훨씬 적습니다. 정규식 라이브러리는 큰 것입니다. 식별자를 파싱하기 위해 하나를 사용하는 것은 우유를 위해 가게에 가기 위해 페라리를 사용하는 것과 같습니다.

그는 정규 표현식이 텍스트 편집기에서 패턴의 일회용 일치에 유용하지만 컴파일 된 코드에는 거의 사용되지 않는 등의 식으로 유용하다고 주장합니다. 읽을 가치가 있습니다.


0

이것은 Alan Perlis의 epigram # 34와 관련이 있습니다.

문자열은 엄청나게 큰 데이터 구조이며 전달되는 곳마다 프로세스가 많이 중복됩니다. 정보를 숨기는 데 완벽한 수단입니다.

따라서 문자열을 데이터 구조로 선택하면 (그리고 자연스럽게 정규식 기반 코드를 조작하는 알고리즘으로), 작동하더라도 문제가 있습니다. 부적절한 데이터 표현 주위의 나쁜 디자인 확장하고 비효율적입니다.

그러나 종종 작동하지 않습니다. 원래 문제는 해결되지 않으므로이 경우 두 가지 문제가 있습니다.


0

정규식은 빠르고 더러운 텍스트 구문 분석에 널리 사용됩니다. 그것들은 단순한 문자열 매치보다 조금 더 복잡한 패턴을 표현하는 훌륭한 도구입니다.

그러나 정규 표현식이 더 복잡한 서버 문제를 겪으면서 고개를 들었습니다.

  1. 정규 표현식의 구문은 간단한 일치에 최적화되어 있으며 대부분의 문자는 자체 일치합니다. 간단한 패턴에는 좋지만 몇 단계 이상의 중첩이 발생하면 잘 구성된 코드보다 라인 노이즈와 비슷한 것으로 끝납니다. 코드 구조를 보여주기 위해 들여 쓰기와 주석이있는 일련의 연결된 문자열로 정규 표현식을 작성할 수 있지만 실제로는 거의 발생하지 않는 것 같습니다.
  2. 특정 유형의 텍스트 일치 만 정규 표현식에 적합합니다. 종종 어떤 종류의 마크 업 언어 작업을 위해 빠르고 더러운 정규식 기반 파서를 얻는 것을 발견하지만 더 많은 코너 사례를 다루려고하면 정규 표현식이 점점 더 복잡해지고 읽기 어려워집니다.
  3. 정규 표현식의 시간 복잡성은 분명하지 않을 수 있습니다. 일치 할 때 훌륭하게 작동 하지만 특정 비 일치의 경우 O (2 ^ n) 복잡성 을 갖는 패턴으로 끝나는 것은 어렵지 않습니다 .

따라서 텍스트 처리 문제로 시작하고 정규 표현식을 적용하고 해결하려는 원래 문제를 해결하려는 원래 문제 (그러나 올바르게 해결하지는 않음)라는 두 가지 문제로 끝납니다. 원래 문제.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.