こんにちは。次の文字列を含む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
許可します。ビデオ全体が1行に含まれると予想しています(より強力なバージョンでは複数行の文字列を受け入れることができますが、このスクリプトではそうではありません)。複数の入力ファイルを一度に処理できます(例:)、見つかった誤った行の行番号とファイル名を知らせます。type
\s*
=
*.md
$type
youtubeやvimeoだけでなく、すべての値を受け入れるには、3行目を次のように置き換えます。
($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
。