안녕하세요. 다음 문자열이 포함된 md 파일이 있고 이에 대한 정규식을 작성하고 싶습니다.
상황
- ID는 무엇이든 될 수 있습니다.
- 유형은 youtube, vimeo 등입니다.
- ID와 종류는 필수항목입니다.
{% include video.html id="T3q6QcCQZQg" type="youtube" %}
그래서 bash 스크립트의 문자열 형식이 올바른지 확인하고 싶습니다. 그렇지 않으면 오류가 나타납니다.
현재 코드는 다음과 같습니다. 아래 코드는 ID 없이도 작동합니다. 하지만 ID에 대한 정규식도 추가해야 합니다.
IFS=$'\n' read -r -d '' -a VIDEOS < <( grep "video.html" "$ROOT_DIR$file" && printf '\0' )
#output => {% include video.html id="T3q6QcCQZQg" type="youtube" %}
for str in "${VIDEOS[@]}"
do
if [[ "$str" =~ ({%)[[:space:]](include)[[:space:]](video.html)[[:space:]](type="youtube"|type="vimeo")[[:space:]](%})$ ]]; then
flag="dummy"
echo "Invalid format:: $second"
fi
done
도와주세요
답변1
원칙적으로는 거의 다 왔습니다. 다음은 귀하가 제공한 예제 콘텐츠를 기반으로 테스트 가능한 최소 정규식 버전입니다.
#!/bin/bash
VIDEOS=( '{% include video.html id="T3q6QcCQZQg" type="youtube" %}' '{% include video.html id="330853122" type="vimeo" %}' '{% include video.html id="330853122" type="nosuchplatform" %}')
regex='^\{% include video.html id="[^"]+" type="(youtube|vimeo)" %\}$'
for v in "${VIDEOS[@]}"
do
if [[ "$v" =~ $regex ]]
then
echo "$v : valid"
else
echo "$v : invalid"
fi
done
id
다음 구조는 변경 필드를 일치시키는 데 사용할 수 있습니다 "[^"]+"
. 즉, "시작 "
뒤에 임의의 항목이 옵니다."아니요a "
, 그 뒤에 "
"가 옵니다. 필드에 허용되는 문자를 알고 있는 경우 id
더 구체적으로 만들 수 있습니다. 즉, 영숫자 문자만 사용할 수 있다는 것을 알고 있는 경우 "[[:alnum:]]+"
대신 시도해 보세요.
정규식을 쉘 변수에 저장하면 정규식을 작성할 때 직면하는 몇 가지 문제를 피할 수 있습니다.아니요테스트에 변수를 사용할 때 변수를 참조하세요.
또한 정규 표현식이 출력하려는 내용과 일치하는 경우 valid
(현재는 =~
테스트 성공을 "잘못된" 패턴으로 처리함) 가정합니다.
답변2
id
및 태그가 (아마도) 이 순서대로 있을 필요는 없으므로 type
일련의 정규식 테스트를 사용하겠습니다.
for str in "${VIDEOS[@]}"; do
if [[ $str =~ \{%[[:blank:]]+include[[:blank:]]+.*[[:blank:]]+%\} ]] &&
[[ $str =~ \<id=\"[^\"]+\" ]] &&
[[ $str =~ \<type=\"(youtube|vimeo)\" ]]
then
echo "valid"
else
echo "invalid"
fi
done
답변3
bash
다른 프로그램의 실행을 조정하는 데는 훌륭하지만 텍스트 처리에는 형편없는 언어입니다. 이렇게 하려면 awk
or를 사용해야 합니다. perl
바라보다쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?.
예를 들어, Perl "one-liner"를 사용하면 다음과 같습니다.
$ perl -lne 'next unless m/{%.*video\.html.*%}/;
($id) = m/\bid\s*=\s*"([^"]+)"/i;
($type) = m/\btype\s*=\s*"(youtube|vimeo)"/i;
print "Invalid format on line $. of $ARGV: $_" unless ($id && $type);' *.md
이는 줄의 어느 위치에서나 순서에 관계없이 허용되며 기호 주위에 선택적 추가 공백( )도 id
허용 합니다 . 전체 비디오가 한 줄에 포함될 것으로 예상합니다(더 강력한 버전에서는 여러 줄 문자열을 허용할 수 있지만 이 스크립트에서는 그렇게 하지 않습니다). 여러 입력 파일을 한 번에 처리할 수 있으며(예 : ) 발견된 잘못된 줄의 줄 번호와 파일 이름을 알려줍니다.type
\s*
=
*.md
$type
youtube 또는 vimeo뿐만 아니라 모든 값을 허용하려면 세 번째 줄을 다음으로 바꾸십시오.
($type) = m/\btype\s*=\s*"([^"]+)"/i;
아니면 교대로 허용되는 유형을 더 추가하세요.
독립 실행형 실행 파일과 동일한 스크립트:
#!/usr/bin/perl
use strict;
while(<>) {
chomp;
next unless m/{%.*video\.html.*%}/;
my ($id) = m/\bid\s*=\s*"([^"]+)"/i;
#my ($type) = m/\btype\s*=\s*"([^"]+)"/i;
my ($type) = m/\btype\s*=\s*"(youtube|vimeo)"/i;
print "Invalid format on line $. of $ARGV: $_\n" unless ($id && $type);
}
예를 들어 verify-videos.pl
PATH(예: ~/bin/
또는 /usr/local/bin/
) 의 어딘가에 저장하고 chmod +x /path/to/verify-videos.pl
.