[번역] 정규 표현 식 을 좀 더 재미있게!
저자: 마 틴 파 울 러
번역자: Abbey (전재 출처 및 번역 자 를 밝 혀 주 십시오)
[2009 년 7 월 24 일 집필]
하나의 방대 한 방법 을 몇몇 좋 은 이름 을 가 진 작은 방법 으로 분해 하 는 것 은 우리 가 유지보수 가능 한 코드 를 작성 할 때 매우 효과 적 인 방법 이다.이 기법 은 Kent Beck 에 의 해 조합 방법 모드 (Composed Method Pattern) 라 고 명명 되 었 다.
사람들 이 당신 의 프로그램의 세부 사항 을 더욱 추상 적 이 고 블록 적 인 방식 으로 이해 할 수 있 을 때, 그들 은 당신 의 프로그램 을 더욱 빠 르 고 정확하게 전면적으로 읽 을 수 있 습 니 다.Kent Beck
제 시 도 를 통 해 이러한 분 치 방식 은 프로그램 에서 의 방법 뿐만 아니 라 사람들 을 괴 롭 히 는 정규 표현 식 분야 에 도 적용 된다 는 것 을 알 게 되 었 습 니 다.
만약 에 체인 호텔 에 상주 하 는 손님 명단 이 있다 고 가정 하고 지 정 된 규칙 에 따라 손님 이 얻 은 포 인 트 를 통계 해 야 한다.예 를 들 어 "Minas Tirith Airport 에서 2 박 숙박 하 는 사람 은 400 포인트 의 포 인 트 를 받 을 수 있 습 니 다." 그러면 우 리 는 이 규칙 설명 에서 포인트 포인트 포인트 400, 숙박 일수 2, 그리고 입주 하 는 호텔 이름 Minas Tirith Airport 라 는 세 가지 우리 가 관심 을 가 지 는 내용 을 순서대로 꺼 내야 합 니 다.
물론 정규 표현 식 은 이런 문제 에 대해 여 유 를 가진다.그리고 나 는 당신 이 이러한 정규 표현 식 을 곧 쓸 수 있 을 것 이 라 고 믿 습 니 다. 그리고 그룹 을 나 누 어 상기 세 가지 내용 을 얻 을 수 있 습 니 다.
const string pattern = @"^score\s+(\d+)\s+for\s+(\d+)\s+nights?\s+at\s+(.*)";
이 정규 표현 식 을 이해 하고 정확 한 지 확인 하려 면 자 연 스 러 운 지 모 르 겠 습 니 다.하지만 나 같 으 면 무슨 말 을 하고 있 는 지 곰 곰 이 생각해 볼 것 이다.나 는 이 정규 표현 식 이 어떻게 조직 되 었 는 지 확인 하기 위해 작은 괄호 를 하나씩 분석 할 것 이다.(실제로 이 예 는 매우 간단 하기 때문에 비슷 하고 복잡 한 상황 을 완전히 반영 하지 못 할 수도 있다.)
아마도 당신 은 아래 와 같은 방식 으로 정규 표현 식 을 쓰 고 해당 하 는 주석 을 표시 하 는 것 을 권 고 받 았 을 것 입 니 다.(프로그램 에서 이러한 정규 표현 식 을 진정 으로 사용 하려 면 적당 한 수정 과 변환 이 필요 합 니 다.)
protected override string GetPattern()
{
const string pattern =
@"^score
\s+
(\d+) # points
\s+
for
\s+
(\d+) # number of nights
\s+
night
s? #optional plural
\s+
at
\s+
(.*) # hotel name
";
return pattern;
}
상술 한 방식 을 채택 하 는 것 은 이해 에 매우 도움 이 되 지만, 나 는 줄곧 주석 을 그다지 좋아 하지 않 는 다.물론 주석 이 나쁘다 고 말 하 는 것 은 아니다. 비록 나 는 항상 이 로 인해 사람들 에 게 비판 을 받는다.더 좋 은 선택 이 있 을 때 왜 주석 이라는 서 툰 방식 을 사용 해 야 하 는가?사실 나 는 지루 한 주석 에 의존 하 는 것 이 아니 라 좋 은 이름과 구 조 를 통 해 코드 의 의 미 를 표현 하고 싶다.(내 가 항상 성공 하 는 것 은 아니 지만 아무것도 하지 않 는 것 보다 낫다.)
비록 사람들 은 일반적으로 정규 표현 식 을 구조 화 하려 고 시도 하지 않 지만, 나 는 이렇게 하 는 것 이 매우 유익 하 다 는 것 을 발견 했다.예 를 들 어 다음 과 같다.
const string scoreKeyword = @"^score\s+";
const string numberOfPoints = @"(\d+)";
const string forKeyword = @"\s+for\s+";
const string numberOfNights = @"(\d+)";
const string nightsAtKeyword = @"\s+nights?\s+at\s+";
const string hotelName = @"(.*)";
const string pattern = scoreKeyword + numberOfPoints + forKeyword
+ numberOfNights + nightsAtKeyword + hotelName;
나 는 정규 표현 식 을 여러 개의 작은 부분 으로 나 누 어 표현 하려 고 시도 했다. 잠시 후에 완전한 정규 표현 식 을 구성 하려 고 한다.이렇게 하면 나 는 0 을 쌓 아 전체 표현 식 을 쉽게 이해 할 수 있다.더 나 아가 우 리 는 공백 문 자 를 나타 내 는 부분 도 제거 하여 더욱 의미 있 게 할 수 있다.이렇게:
const string space = @"\s+";
const string start = "^";
const string numberOfPoints = @"(\d+)";
const string numberOfNights = @"(\d+)";
const string nightsAtKeyword = @"nights?\s+at";
const string hotelName = @"(.*)";
const string pattern = start + "score" + space + numberOfPoints + space
+ "for" + space + numberOfNights + space + nightsAtKeyword
+ space + hotelName;
이렇게 하면 공백 문 자 를 나타 내 는 부분 을 더욱 선명 하 게 하지만 전체 표현 식 의 구조 복잡 도 를 증가 시 킬 수 있다.그래서 나 는 이전의 그 실현 이 더 좋다.그러나 그것 도 완벽 한 것 은 아니다. 잡 으 려 는 모든 요 소 를 빈 칸 으로 구분 해 야 하기 때문에 약간의 우물쭈물 을 피 할 수 없다.이 를 위해, 나 는 각 하위 표현 식 을 조합 하 는 방법 을 추가 했다.
private String composePattern(params String[] arg)
{
return "^" + String.Join(@"\s+", arg);
}
그래서 GetPattern 방법 은 이렇게 되 었 습 니 다.
const string numberOfPoints = @"(\d+)";
const string numberOfNights = @"(\d+)";
const string hotelName = @"(.*)";
const string pattern = composePattern("score", numberOfPoints, "for", numberOfNights, "nights?", "at", hotelName);
물론, 너 는 반드시 내 가 말 한 대로 해 야 한다.나 는 단지 네가 가능 한 한 너의 정규 표현 식 을 더욱 의미 있 고 명확 하 게 읽 을 수 있 기 를 바 랄 뿐, 힘 든 추측 이 필요 없다.
[2014 년 7 월 31 일 업데이트]
이전에 나 는 조합 정규 표현 식 의 각 부분 을 저장 하기 위해 부분 변 수 를 사용 했다.더 넓 은 범위 에서 사용 해 야 한다 면 구조 가 더 통용 되 는 정규 표현 식 과 같은 적절 한 개선 을 할 수 있 습 니 다.이에 대해 제 동료 카 를 로 스 빌 라 는 이러한 구성 식 의 각 부분 이 적절하게 조합 되 지 않 으 면 괄호 가 열 리 고 닫 히 고 짝 이 맞지 않 으 면 프로그램의 Bug 를 야기 할 것 이 라 고 지적 했다.나 는 이런 걱정 은 불필요 하 다 고 생각 하 니, 우 리 는 무시 합 시다.
정규 표현 식 대신 더 의미 있 는 Fluent API (내부 DSL 언어) 를 사용 하 자 는 의견 도 있다.나 는 이것 이 완전히 다른 일이 라 고 생각한다.너무 복잡 한 상황 이 아니라면, 나 는 복잡 한 Fluent API 보다 가 벼 운 정규 표현 식 을 사용 하고 싶다.물론 이것 은 네가 어떻게 선택 하 느 냐 에 달 려 있다.
명명 포획 을 사용 하면 된다 는 의견 도 있다.주석 을 대 하 는 태도 처럼 나 는 이것 이 확실히 원생 의 정규 표현 식 보다 좋 지만 구조 화 된 정규 표현 식 보다 못 하 다 고 생각한다.여러 조각 으로 나 뉘 어 진 정규 표현 식 은 항상 완전한 표현 식 보다 이해 하기 쉽 기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.