文字列の正規表現

文字列の正規表現

こんにちは。次の文字列を含むmdファイルがあり、そのための正規表現を作成したいと思います。

状況

  1. IDは何でも構いません。
  2. タイプはyoutube、vimeoなどです。
  3. 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他のプログラムの実行を調整するのは素晴らしいですが、テキスト処理には不都合な言語です。これを行うには、awkorを使用する必要があります。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

$typeyoutubeや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.plPATH(たとえば、~/bin/または/usr/local/bin/)のどこかに保存しますchmod +x /path/to/verify-videos.pl

関連情報