regex - 使用 Bash 正则表达式匹配单词边界

标签 regex bash word-boundary

我想在 bash 中匹配以下表达式:

^.*(\b((720p)|(1080p)|(((br)|(hd)|(bd)|(web)|(dvd))rip)|((x| h)264)|(DVDscr)|(xvid)|(hdtv)|(ac3)|(s[0-9]{2}e[0-9]{2})|(avi)|(mp4)| (mkv)|(eztv)|(YIFY))\b).*$

我真的只想知道被测试的字符串中的一个词是否是这个正则表达式中描述的词之一(720p1080p brrip, ...)。边界这个词似乎有问题。

我使用的测试是 [[ $name =~ $re ]] && echo "yes" 其中 $name 是任意字符串,$re 是我的正则表达式。

我错过了什么?

最佳答案

\b 是 PCRE 扩展;它在 POSIX ERE(扩展正则表达式)中不可用,它是 bash 的 [[ ]] 中的 =~ 运算符将遵循的最小可能语法集。 (单个操作系统可能有一个扩展此语法的 libc;在这种情况下,这些扩展将在此类操作系统上可用,但并非在所有支持 bash 的平台上)。

作为基准,\b 扩展实际上没有太多的表达能力——您可以编写任何将它用作等效 ERE 的 PCRE。不过,更好的办法是退后一步,质疑潜在的假设:当你说“单词边界”时,你真正的意思是什么?如果您所关心的是如果它以空格或字符串的开头或结尾开始和结束,那么您根本不需要 \b 运算符:

(^|[[:space:]])((720p)|(1080p)|(((br)|(hd)|(bd)|(web)|(dvd))rip)|((x|h)264)|(DVDscr)|(xvid)|(hdtv)|(ac3)|(s[0-9]{2}e[0-9]{2})|(avi)|(mp4)|(mkv)|(eztv)|(YIFY))($|[[:space:]])

请注意,我去掉了开头的 ^.* 和结尾的 .*$,因为这些结构在进行非锚定匹配时会 self 否定; .* 使紧接在它前面的 ^ 变得毫无意义,同样地 .* 就在最后的 $ 之前.


现在,如果你想要一个 exact 等同于 \b 紧接在序列开头的单词字符之前,那么我们会得到更像的东西:

(^|[^a-zA-Z0-9_])

...同样,当紧跟在序列末尾的单词字符之后时:

($|[^a-zA-Z0-9_])

这两种情况都有些退化——在其他情况下,在 ERE 中模拟 \b 的行为可能会更复杂——但它们是你的问题出现的唯一情况.

请注意,\b 的某些实现会更好地支持非 ASCII 字符集,因此可以用 [^[:alnum:]_] 更好地描述而不是 [^a-zA-Z0-9_],但这里没有明确定义您来自哪个实现或与之比较。

关于regex - 使用 Bash 正则表达式匹配单词边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27476347/

相关文章:

正则表达式查询 : any from list bracketing central term

bash - 在 bash 4 中将每个单词的第一个字符设置为大写,将其他字符设置为小写?

linux - BASH 脚本 -> ssh server_name sudo -u 用户 sqlplus 查询 -> 进入变量

python - 如何在 pandas str.contains 中使用\b 字边界?

regex - 如何在不使用 match() 函数的情况下在 awk 中使用单词边界?

正则表达式匹配任何带引号的字符串或特定的不带引号的字符串

python - 如何捕获多个可选组

php - 使用PHP正则表达式提取TLD

bash - Bash 如何对脚本进行标记?

javascript - 单词边界对符号字符有效吗?