匹配零个或多个以逗号分隔的关键字

匹配零个或多个以逗号分隔的关键字

我想匹配零个或多个用逗号分隔的关键字的可能性。

我使用以下正则表达式

if [[ "$var" =~ ^([^,]+(,[^,]+)*)*$ ]]; then
  echo "KY MATCH"
fi

我想匹配以下内容

var=""
var="keyword"
var="keyword,keyword"
var="keyword,keyword,keyword"

正则表达式可以简化或更清晰吗?

答案1

Bash 使用 POSIX 扩展正则表达式 - try info bash -n 'Conditional Constructs'and man 7 regex(对于第一个命令,您需要安装info,对于第二个命令man-pages)。

如果您的关键字仅包含字母,您可以使用[:alpha:]字符类,也可以使用[:alnum:]or [:word:]

尝试这个脚本并选择正确的类:


#!/bin/bash

for var in "" "keyword" "keyword,keyword" "keyword,keyword,keyword"; do
    [[ "$var" =~ ^([[:alpha:]]+,?)*$ ]] && echo "$var" MATCHES || echo "$var" DOES NOT MATCH
done

for var in "1" "key word" "key123word,keyword" "keyword, keyword ,keyword"; do
    [[ "$var" =~ ^([[:alpha:]]+,?)*$ ]] && echo "$var" MATCHES || echo "$var" DOES NOT MATCH
done

更新

正如评论中所说,我的表达方式不适用于此 - keyword,keyword,。这个表达方式似乎很合适^([[:alpha:]]+(,[[:alpha:]]+)*)*$——我不明白如何让它变得更简单。

答案2

如果将逗号分隔的关键字转换为如下的正则表达式,则可以更容易:

#!/usr/bin/env -S bash - 

#keywords="keyword"
#keywords="aaa,bbb,ccc"
keywords="aaa,bbb,ccc,"
#keywords="ddd,"
#keywords=""

var='aaa'
regex="${keywords%,}"   # trim trailing ','
regex="${regex//,/\|}"  # replace ',' with '|'

printf 'Your var  : %s\n' "$var"
printf 'Your regex: %s\n' "$regex"

if [[ $var =~ ^($regex)$ ]]; then
    printf '%s\n' '-> it matches'
else
    printf '%s\n' '-> it does not match'
fi

这导致

$ temp/match-comma-separated-keywords.sh
Your var: aaa
Your regex: aaa|bbb|ccc
-> it matches

答案3

看起来您想要排除的唯一内容是空,分隔字段,但没有字段的特殊情况除外,因此排除,第一个或最后一个或有两个连续字符串的字符串,因此:

case $string in
  (,* | *,,* | *,) echo>&2 not OK;;
  (*) echo OK;;
esac

或者

case ,${string:-empty}, in
  (*,,*) echo>&2 not OK;;
  (*) echo OK;;
esac

这是标准 POSIX sh 语法,或使用 Korn 风格的语法:

[[ ,${string:-empty}, != *,,* ]]。不需要=~

一个正则表达式可能是:

[[ $string, =~ ^([^,]+,)*$ ]]

不过,您可以使用通配符模式来完成此操作,而不必求助于系统的正则表达式引擎以及可能随之而来的问题(例如它因非字符而窒息):

[[ $string, = *(+([^,]),) ]]

相关内容