字符串的正则表达式

字符串的正则表达式

您好,我有一个包含以下字符串的 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:]]+"改为。

通过将正则表达式存储在 shell 变量中,您可以避免在制定正则表达式时遇到的一些问题,只需确保不是在测试中使用变量时引用该变量。

我还假设,如果正则表达式与您想要输出的匹配valid(目前您会将=~测试的成功视为“无效”模式)。

答案2

由于idtype标签(可能)不需要按这个顺序,我会使用一系列正则表达式测试:

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为什么使用 shell 循环处理文本被认为是不好的做法?

例如,使用 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

这允许idtype可以在行中的任何位置采用任何顺序,并且还允许在符号\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.plPATH 中的某个位置(例如~/bin//usr/local/bin/)并使用chmod +x /path/to/verify-videos.pl.

相关内容