2009-06-05 5 views
9

나는 Perl의 정규식을 통해 느슨한 단어 래핑 시스템을 만들려고합니다. 내가 좋아할만한 것은 70 자 정도이다. 다음 공백 발생을 확인하고 그 공백을 개행 문자로 바꾼 다음 전체 문자열에 대해 이렇게한다. 내가 조작하고있는 문자열에 이미 이미 개행 문자가있을 수 있지만 개행 문자 사이의 텍스트 양은 매우 길어지는 경향이 있습니다.어떻게 단어를 Perl에서 문자열로 감쌀 수 있습니까?

한 번에 하나의 문자를 반복하거나 가능한 경우 substr을 사용하지 말고 새로운 문자열 객체를 만드는 대신이 문자열을 편집하는 것이 좋습니다. 이것들은 단지 기본 설정 일 뿐이며, 이러한 기본 설정을 깨지 않으면 서 내가 원하는 것을 얻을 수 없다면 괜찮습니다.

생각하십니까?

+1

공백 대신에 단어 경계에 일치하는 \ b로 표시된 문자 집합이 있습니다.이 문자 집합은 좀 더 강력 할 수 있습니다. – jiggy

+2

@jiggy \ b는 문자 클래스가 아니며 폭이 0 인 어설 션입니다. –

+2

게다가, "강조!"단어 사이에 구두점이 생길 수 있으며, 그 단어가 구두점을 벗어날 수 있습니다. 그리고 그것은 단지 잘못되었습니다. ! – Axeman

답변

11

처음 70자를 소비 한 후 다음 공백에서 멈추고 프로세스의 모든 것을 캡처합니다. 그런 다음, 끝에서 공백을 생략하고 줄 바꿈을 추가하여 캡처 한 문자열을 내 보냅니다.

이렇게해도 줄 바꿈이 80 자 또는 그 이상으로 엄격히 제한되지는 않습니다. 마지막으로 소비하는 단어가 10 억 자 길이되지는 않을 것이라는 보장은 없습니다.

+1

저는 71.에서"as in a "를 시작하면. {70,80} \ s + – Axeman

+0

@Axeman은 정확하지만 욕심 많은 평가 (최대한 많은 내용을 찾으려고 함) 덕분에 너는 70 줄 길이의 {1,70}을 원한다. 나는 대답을 편집했다. –

+1

linebreaks를 정상적으로 처리 할 수있는보다 진보 된 정규 표현식은's/(. {1,70} | \ S {71,})이 될 것입니다 (? 나는 공식적인 대답을 간단하게하고 싶었 기 때문에 나는 그것을 버렸다. –

22

Text::Wrap 또는 Text::Autoformat과 같은 모듈을 살펴보십시오.

필요에 따라 GNU 코어 유틸리티 fold (1)조차도 옵션 일 수 있습니다.

+1

아마 그게 최선의 방법 일 것이다. - 일부는 예외 일 것이다. (예를 들어, \\ s \\ s \ r \ n] 고아 구문의. – Axeman

+0

사실 난 그냥 발견 : 텍스트 : : 랩 : : 스마트 단어가 있다면 라인을 끊는 중지 정의 된 메시지 크기보다 큼. – RushPL

7

Welbog의 대답은 70 자 뒤 첫 번째 공백으로 바뀝니다. 이것은 라인의 끝 부분 가까이에서 시작하는 긴 단어가 겹치는 선을 만드는 결점이 있습니다. 당신은> 80 문자 "단어를"이 경우에만 진정한 깨지지 않는 선이 너무 긴 것을, 그래서 나는, 말, 처음으로 81 자 이내의 마지막 공간에 포장, 또는 최초의 우주에서 포장 대신 제안 :

s/(.{1,79}\S|\S+)\s+/$1\n/g; 
현대 펄에서

:

s/(?:.{1,79}\S|\S+)\K\s+/\n/g; 
+1

D' oh! 그리고 나는 심지어 이런 종류의 일을 여러 번 해왔다. – Axeman

5

당신은 훨씬, 훨씬 더 제어 및 신뢰성을 얻을 수 Text::Format

use Text::Format; 
print Text::Format->new({columns => 70})->format($text); 
1

이를 사용하여 내가 항상 사용했던 것입니다.

정말 긴 문자열 (예 : URL)이있는 경우가 아니면 랩 길이 (이 경우 75 자)를 감싸기 시작합니다.이 경우에는 해당 문자열을 자신의 라인을 깨뜨리기보다는.

s/(?=.{70,})(.{0,70}\n?)()/\1\2\n /g 

이 두 번째 형태는 모든 라인 엔딩을 처리 : 맥 \ r에, 유닉스 \ n, 윈도우 \ 연구 \ n 및 텔레 \ n 개의 \ r에 있지만, 어느 하나를 대체 여전히 넣어에 따라 달라집니다로 사용 replacement 절에서 : 나는 \ n을 사용했다. 당신이 것을 원하지 않는 경우 마지막/g 전에 공간을 제거 할 수 있지만 나는 보통이 좋네요 찾을 :

s/(?=.{70,})(.{0,70}(?:\r\n?|\n\r?)?)()/\1\2\n /g 

두 버전은 하나의 공백으로 첫 결국 포장 라인을 들여.

관련 문제