문자열에 ASCII 공백 문자가 포함되어 있는지 테스트하는 방법은 무엇입니까?

문자열에 ASCII 공백 문자가 포함되어 있는지 테스트하는 방법은 무엇입니까?

문자열에 공백 문자가 있는지 확인하는 방법은 무엇입니까? 유니코드 너비가 0인 문자 등 ASCII 이외의 항목에 대해 걱정할 필요가 없습니다. 문자열이 셸 변수(예: )에 저장되어 있다고 가정할 수 있습니다 $string.

동작 예:

abc공백이 있으므로 true를 반환합니다.

\tabc탭이 있으므로 true를 반환합니다.

abc공백 문자가 없으므로 false를 반환해야 합니다.

abc
hello

개행 문자가 있으므로 true를 반환해야 합니다.


일반적인 명령줄 유틸리티( sed, grep, awk, bash)를 사용하는 솔루션이면 충분합니다.

답변1

POSIX sh 구문에서:

case $string in
  (*[[:blank:]]*) echo "string contains at least one character classified as blank";;
  (*[[:space:]]*) echo "string contains at least one character classified as whitespace (but not blank)";;
  (*) echo no character classified as whitespace;;
esac

[:blank:]의 하위 집합이어야 합니다 [:space:]. [:blank:]최소한 공백과 TAB 및 [:space:]최소한 공백, TAB, NL, CR, FF 및 VT를 포함하도록 보장됩니다.

이는 사용된 인코딩과 로케일의 문자 분류를 기반으로 합니다. 대부분의 시스템에서 모든 로케일은 ASCII 문자 세트 또는 ASCII 상위 세트를 사용합니다(일부 일본어 로케일의 일부 BSD에 있는 MS-Kanji를 무시하는 경우 0x5c가 대신 사용됩니다 ¥( 문자 \가 없습니다 \!). 나머지는 ASCII 상위 집합).

$stringEBCDIC 기반 시스템에서도 하나 이상의 ASCII 인코딩이 포함된 ASCII 공백을 확인하려면 바이트 값 세트를 지정하거나 iconv테마를 현재 문자 세트에서 ASCII로 변환을 사용해야 합니다.

ascii_whitespace=$(printf ' \r\n\r\f\v' | iconv -t ASCII)
# or
ascii_whitespace=$(printf '\40\11\12\13\14\15')
case $string in
  (["$ascii_whitespace"]) echo contains at least one ASCII whitespace;;
esac

( \15해당 시스템에서는 개행 문자가 발생하지 않기를 바랍니다.)

답변2

문자열이 쉘 변수에 저장되어 있다고 가정하십시오 $string. 이 경우 bash셸로 지정했으므로 [[ ... ]]테스트 구성에서 내장 정규식 일치를 사용할 수 있습니다.

if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi

쉘 스크립트에서도 사용할 수 있습니다.

몇 가지 사용 예:

~$ string=" hello "
~$ if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi
Contains whitespace

~$ string=$'\thello'
~$ if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi
Contains whitespace

~$ string="hello"
~$ if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi
Doesn't contain whitespace

노트:이는 POSIX 문자 클래스를 사용합니다 [:space:]. 예를 들어 참조하십시오.

[:space:]와 사이의 미묘함을 위해 [:blank:]. 공백을 만드는 캐릭터만 고려하고 싶다면같은 줄 안에(예: <space>\t)로 전환해야 합니다 [:blank:](그러나 일부 로케일에서는 [:blank:]세로 공백 문자도 포함됩니다).

답변3

사용행복하다(이전의 Perl6)

~$ echo "abc " | raku -ne '.contains(/ \s /).say'
True
~$ echo "abc" | raku -ne '.contains(/ \s /).say'
False

-ne위의 Raku 코드는 awk와 유사한 명령줄 플래그를 사용하여 입력을 한 줄씩 실행합니다. Raku의 contains메서드는 부울 값을 반환합니다. 선행 .점은 contains명령줄에서 입력을 가져옴을 나타냅니다. 또는(또는)표준 입력.

~$ echo "abc " | raku -ne 'say .contains(/ \s /) ?? True !! False;'
    True
~$ echo "abc" | raku -ne 'say .contains(/ \s /) ?? True !! False;'
    False

??위의 내용은 Raku의 삼항 연산자인 Test True False 를 사용하기 때문에 조금 더 복잡합니다 !!. Raku는 논리적 True이고 논리적 False이므로 위의 반환 값을 인용할 필요가 없습니다. 여기서 장점은 Trueand False를 원하는 큰따옴표로 간단히 바꿀 수 있다는 것입니다(예: "Yes"and ) "No".

아마도 OP의 질문에는 다음이 포함됩니다.수평의공백과 관련하여 Raku는 \h가로 공백과 \v세로 공백을 구분할 수 있습니다.

~$ raku -e 'put "abc\t";' | raku -ne 'say .contains(/ \h /);'
True
~$ raku -e 'put "abc\t";' | raku -ne 'say .contains(/ \v /);'
False

OP는 여러 줄의 입력 문자열을 처리해야 하는지 여부를 밝히지 않았습니다. 공백에 대해서는 항상 "양수"이지만 수평 공백에 대해서는 "음수"일 수 있습니다. [숫자 열을 입력으로 생각하세요]. 어쨌든 Raku에서는 위와 같이 한 줄씩 입력을 읽을 수 있으며(기본적으로 자동으로 수행됨), \n이름이 이상하지만 기억에 남는 읽기 입력을 한 번에 사용할 수 있습니다(eol 개행 문자 유지) slurp.

한 줄씩 읽기(autochomps):

~$ raku -e 'put "1\n2\n3";' | raku -ne 'say .contains(/ \h /);'
False
False
False
~$ raku -e 'put "1\n2\n3";' | raku -e 'for lines() {say .contains(/ \h /)};'
False
False
False

한 번에 모든 내용 읽기(자동 씹기 없음):

~$ raku -e 'put "1\n2\n3";' | raku -e 'say slurp.contains(/ \v /);'
True
~$ raku -e 'put "1\n2\n3";' | raku -e 'put slurp.contains(/ \h /);'
False

부록: OP의 진술을 의역하고 있습니다."ASCII 이외의 것에 대해서는 걱정할 필요가 없습니다..."~처럼"유니코드가 처리되든 상관없어요". 만약에오직ASCII 공백이 처리됩니다(다른 모든 공백은 거부됨). 이는 Raku가 관리할 수 있지만 위에서는 다루지 않은 것입니다. Raku는 이미 유니코드를 지원하므로 \s(약어 <space>) 및 \h(약어 <blank>)와 \v둘 다 기본적으로 유니코드를 허용합니다.

ASCII가 아닌(가로) 공백을 거부하려면 다음과 같은 사용자 정의 문자 클래스를 시도해 볼 수 있습니다 <:ASCII> & <blank>.

예:

~$ raku -e 'put "\xA0";' | raku -ne 'put .contains(/ <blank> / );'
True
~$ raku -e 'put "\xA0";' | raku -ne 'put .contains(/ <:ASCII> & <blank> / );'
False

https://docs.raku.org/언어/operators#index-entry-operator_ternary
https://docs.raku.org/언어/regexes#\h_and_\H
https://docs.raku.org/routine/contains
https://raku.org

관련 정보