[regex] 공백과 일치하지만 줄 바꿈과 일치하지 않습니다.
때로는 공백과 일치하지만 개행 문자는 일치시키지 않습니다.
지금까지 나는 의지했습니다 [ \t]
. 덜 어색한 방법이 있습니까?
답변
Perl 버전 5.10 이상은 보조 수직 및 수평 문자 클래스 \v
및 \h
일반 공백 문자 클래스를 지원합니다.\s
가장 깨끗한 해결책은 가로 공백 문자 클래스 를 사용하는 것 \h
입니다. 이것은 ASCII 세트의 탭과 공백, 확장 ASCII의 비 분리 공백 또는 이러한 유니 코드 문자와 일치합니다.
U+0009 CHARACTER TABULATION
U+0020 SPACE
U+00A0 NO-BREAK SPACE (not matched by \s)
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE
수직 공간 패턴은 \v
덜 유용하지만, 이러한 문자와 일치
U+000A LINE FEED
U+000B LINE TABULATION
U+000C FORM FEED
U+000D CARRIAGE RETURN
U+0085 NEXT LINE (not matched by \s)
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
일치하는 7 개의 수직 공백 문자와 일치하는 \v
18 개의 수평 문자가 있습니다 \h
. \s
스물 세 문자와 일치
모든 공백 문자는 겹치지 않고 세로 또는 가로 이지만 \h
U + 00A0 NO-BREAK SPACE와 \v
일치하고 U + 0085 NEXT LINE 과도 일치 하므로 적절한 하위 세트가 아닙니다.\s
답변
이중 음수를 사용하십시오.
/[^\S\r\n]/
즉, 공백이 아님 (자본 S가 보완 함) 또는 캐리지 리턴이 아니거나 줄 바꿈이 아닙니다. 외부를 배포하지 않음 (De Morgan의 법칙으로 즉 , ^
캐릭터 클래스 의 보완) 을 “공백이지만 캐리지 리턴 또는 줄 바꿈이 아님”과 같습니다. 패턴에 및 패턴을 모두 포함하면 모든 Unix (LF), 클래식 Mac OS (CR) 및 DOS-ish (CR LF) 줄 바꿈 규칙을 모두 올바르게 처리합니다 .\r
\n
그것에 대해 내 말을 할 필요가 없습니다.
#! /usr/bin/env perl
use strict;
use warnings;
use 5.005; # for qr//
my $ws_not_crlf = qr/[^\S\r\n]/;
for (' ', '\f', '\t', '\r', '\n') {
my $qq = qq["$_"];
printf "%-4s => %s\n", $qq,
(eval $qq) =~ $ws_not_crlf ? "match" : "no match";
}
산출:
""=> 일치 "\ f"=> 일치 "\ t"=> 일치 "\ r"=> 일치하지 않습니다 "\ n"=> 일치하지 않습니다
세로 탭은 제외하지만 v5.18에서 해결되었습니다. .
너무 거칠게 반대하기 전에 Perl 문서는 동일한 기술을 사용합니다. perlrecharclass 의 “공백”섹션에있는 각주 읽기
Perl v5.18 이전
\s
에는 세로 탭과 일치하지 않았습니다.[^\S\cK]
(모호하게)\s
전통적으로 한 것과 일치합니다 .
perlrecharclass 의 동일한 섹션 에서도 언어 교사의 이중 부정에 대한 반대를 불쾌하게하지 않는 다른 접근법을 제안합니다.
로케일 및 유니 코드 규칙 외부 또는 /a
스위치가 적용되는 경우 ” Perl v5.18부터 세로 탭 ” \s
과 일치 [\t\n\f\r ]
하고 일치 \cK
합니다. ” 폐기 \r
하고 \n
떠날 /[\t\f\cK ]/
일치 공백하지만 줄 바꿈하지 않는.
텍스트가 유니 코드 인 경우 아래에 설명 된 설명서 섹션 의 표에서 패턴을 구성하려면 아래 하위와 유사한 코드를 사용 하십시오 .
sub ws_not_nl {
local($_) = <<'EOTable';
0x0009 CHARACTER TABULATION h s
0x000a LINE FEED (LF) vs
0x000b LINE TABULATION vs [1]
0x000c FORM FEED (FF) vs
0x000d CARRIAGE RETURN (CR) vs
0x0020 SPACE h s
0x0085 NEXT LINE (NEL) vs [2]
0x00a0 NO-BREAK SPACE h s [2]
0x1680 OGHAM SPACE MARK h s
0x2000 EN QUAD h s
0x2001 EM QUAD h s
0x2002 EN SPACE h s
0x2003 EM SPACE h s
0x2004 THREE-PER-EM SPACE h s
0x2005 FOUR-PER-EM SPACE h s
0x2006 SIX-PER-EM SPACE h s
0x2007 FIGURE SPACE h s
0x2008 PUNCTUATION SPACE h s
0x2009 THIN SPACE h s
0x200a HAIR SPACE h s
0x2028 LINE SEPARATOR vs
0x2029 PARAGRAPH SEPARATOR vs
0x202f NARROW NO-BREAK SPACE h s
0x205f MEDIUM MATHEMATICAL SPACE h s
0x3000 IDEOGRAPHIC SPACE h s
EOTable
my $class;
while (/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg) {
my($hex,$name) = ($1,$2);
next if $name =~ /\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .= "\\N{U+$hex}";
}
qr/[$class]/u;
}
다른 응용
이중 음수 트릭은 알파벳 문자를 일치시키는데도 유용합니다. 그 기억 \w
일치 “단어 문자,”알파벳 문자 와 숫자와 밑줄을. 우리는 추악한 미국인들이 때때로 이렇게 말합니다.
if (/[A-Za-z]+/) { ... }
그러나 이중 음수 문자 클래스는 로케일을 존중할 수 있습니다.
if (/[^\W\d_]+/) { ... }
이런 방식으로“단어 나 밑줄이 아닌 단어 문자”를 표현하는 것은 약간 불투명합니다. POSIX 문자 클래스는 의도를보다 직접적으로 전달합니다
if (/[[:alpha:]]+/) { ... }
또는 szbalint가 제안한 유니 코드 속성
if (/\p{Letter}+/) { ... }
답변
캐리지 리턴을 포함 하는 Greg의 답변 변형 :
/[^\S\r\n]/
이 정규식은 /[^\S\n]/
no 보다 안전 \r
합니다. 내 추론은 Windows가 줄 \r\n
바꿈에 사용하고 Mac OS 9는 사용했습니다 \r
. 요즘 \r
없이는 찾을 수 없지만 찾을 \n
경우 개행을 의미 할 수는 없습니다. 따라서 \r
개행을 의미 할 수 있기 때문에 개행도 제외해야합니다.
답변
아래 정규식은 공백과 일치하지만 줄 바꿈 문자는 일치하지 않습니다.
(?:(?!\n)\s)
당신은 또한 캐리지 리턴을 추가 할 경우 추가 \r
에 |
부정적인를 내다 내부 연산자.
(?:(?![\n\r])\s)
+
캡처하지 않은 그룹 뒤에 추가 하여 하나 이상의 공백을 일치시킵니다.
(?:(?![\n\r])\s)+
사람들이 왜 [[:blank:]]
수평 공백 ( 공백 및 탭)과 일치 하는 POSIX 문자 클래스를 언급하지 못한 지 모르겠습니다. ) . 이 POSIX chracter 클래스는 BRE ( Basic REgular Expressions ), ERE ( Extended Regular Expression ), PCRE ( Perl Compatible Regular Expression )에서 작동합니다.
답변
당신이 찾고있는 것은 POSIX blank
문자 클래스입니다. Perl에서는 다음과 같이 참조됩니다.
[[:blank:]]
자바에서 (활성화하는 것을 잊지 마십시오 UNICODE_CHARACTER_CLASS
) :
\p{Blank}
유사한 \h
POSIX blank
는 몇 가지 정규식 엔진 ( 참조 )에서 지원됩니다 . 주요 이점은 그 정의가 부록 C : 유니 코드 정규 표현식의 호환성 속성에 고정되어 있다는 것입니다 를 지원하는 모든 에서 표준 있다는 것입니다. (예를 들어, Perl에서는 \h
을 추가로 선택합니다 MONGOLIAN VOWEL SEPARATOR
.)\h
POSIX 문자 클래스는 종종 기본적으로 ASCII 인 반면, 엔진은 어느 엔진에 동의하지 않더라도 항상 유니 코드 문자를 감지합니다. -전용 (Java와 동일).
그러나 문제는 유니 코드를 고수하더라도 100 % 문제를 해결하지 못한다는 것입니다. 유니 코드에서 공백으로 간주되지 않는 다음 문자를 고려하십시오.
-
U + 180E 몽골 보울 분리기
-
U + 200B 제로 폭 공간
-
U + 200C ZERO WIDTH NON-JOINER
-
U + 200D ZERO WIDTH JOINER
-
U + 2060 워드 조이너
-
U + FEFF ZERO WIDTH NON-BREAKING SPACE
앞서 언급 한 몽골어 모음 분리기는 좋은 이유가 포함되어 있지 않습니다. 200C 및 200D와 함께 단어 (AFAIK)에서 발생하므로 다른 모든 공백이 준수하는 기본 규칙을 위반합니다. 토큰으로 토큰 화 할 수 있습니다. 그것들은 더 많은 수정 자와 같습니다. 그러나 ZERO WIDTH SPACE
, WORD JOINER
및ZERO WIDTH NON-BREAKING SPACE
(가 바이트 순서 표시 이외로 사용 된 경우) 내 책에 공백 규칙에 맞게. 따라서 수평 공백 문자 클래스에 포함시킵니다.
자바에서 :
static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
답변
m/ /g
에 공간을 주면 / /
작동합니다. 또는 사용 \S
— 탭, 줄 바꿈, 공백 등의 모든 특수 문자를 대체합니다.