Regex 带有可选字符和最小/最大长度的正则表达式匹配模式

Regex 带有可选字符和最小/最大长度的正则表达式匹配模式,regex,grep,Regex,Grep,匹配以X开头,后面是3到6个大写单词或数字,必须至少包含一个字母,并且可以有可选的破折号-。 匹配的示例: XABC XA-BC8D X-ABC XB72D- 不匹配的示例: X123 //no letters XAB //too short XABC-123 //too long XA--BC //too many - 我尝试了X(?=.{3,6}$)[A-Z0-9]*-?[A-Z0-9]*,但它有很多问题。它可以匹配类似于X---的内容。正则表达式应与gre

匹配以X开头,后面是3到6个大写单词或数字,必须至少包含一个字母,并且可以有可选的破折号-。 匹配的示例:

XABC
XA-BC8D
X-ABC
XB72D-
不匹配的示例:

X123      //no letters
XAB       //too short
XABC-123  //too long
XA--BC    //too many -

我尝试了
X(?=.{3,6}$)[A-Z0-9]*-?[A-Z0-9]*
,但它有很多问题。它可以匹配类似于
X---
的内容。正则表达式应与grep兼容。

您可以使用
-p
(PCRE)将此正则表达式与
gnu grep
一起使用:

grep-P'^X(?([^-]*-){2})(?=[^A-Z]*[A-Z])[A-Z\d-]{3,6}$'文件
XABC
XA-BC8D
X-ABC
XB72D-

正则表达式详细信息:

  • ^
    :开始
  • X
    :匹配字母
    X
  • (?!([^-]*-){2})
    :负向前看,断言前面永远不会有多个连字符
  • (?=[^A-Z]*[A-Z])
    :正向前瞻,以断言前面至少有一个大写字母
  • [A-Z\d-]{3,6}
    :匹配大写字母或数字或
    -
    3到6次
  • $
    :结束

如果您没有安装<代码> GNU-GRP,那么您可以考虑这个代码> AWK < /代码>:


awk-F-'NF您可以使用
-p
选项将
grep
与PCRE模式一起使用(如果
grep
不可用,则使用
pcregrep
):

^X(?)(?:[^-]*-){2}(?=.*\p{Lu})[\p{Lu}\d-]{3,6}$
看。详情:

  • ^
    -字符串的开头
  • X
    -一个
    X
    字符
  • (?!(?:[^-]*-){2}
    -字符串中不能有两个不一定连续的连字符
  • (?=.*\p{Lu})
    -字符串中必须有大写字母
  • [\p{Lu}\d-]{3,6}
    -三到六个字母数字或
    -
    字符
  • $
    -字符串结束
下面是一种使用awk的方法:

awk'/^X[:upper:[:digit:]-]{3,6}$/&&/[:upper:]/{val=$0;sub(“-”,”,val);if(val~/^X[:upper:[:digit:]+$/){print$0;}文件
略为缩短的版本:

awk'/^X[:upper:][:digit:][-]{3,6}$/&&/[:upper:][]/{val=$0;sub(“-”,val);val~/^X[:upper:][:digit:][]+$/}1”文件
看一看。详情:

  • /^X[[:upper:][:digit:][-]{3,6}$/&&/[:upper:][]/
    -行必须包含一个大写字母,该字母不是字符串中的第一个,并且必须与
    ^X[:upper:][:digit:][-]{3,6}$
    模式匹配:
    • ^
      -字符串的开头
    • X
      -a
      X
    • [[:上限:][:数字:][-]{3,6}
      -三到六个字母数字或
      -
      字符
    • $
      -直到字符串结束
  • val=$0;sub(“-”,“,”,val)-将该行分配给
    val
    变量,然后从
    val
    中删除单个
    -
  • if(val~/^X[:upper:[:digit:]+$/){print$0;}}
    -如果
    val
    X
    开头,然后直到字符串末尾只有大写字母或数字,请打印它。在缩短版本中,如果$0~/…/{print$0;}
,则该
替换为
/…/
1
标志(默认情况下,该标志打印整个记录(行))
第一个
x
可以是小写的,对吗?对不起,它应该是大写的,我现在编辑了它。我可以问一下在这个例子中负前瞻是如何工作的,为什么它不需要
{2,}
是的,当然可以,可以在这里自由提问。
(?!([^-]*-{2})
之所以有效,是因为它在输入中找到2个连字符时就会失败。如果断言失败,则不需要匹配超过2个连字符。好的,这很有意义,谢谢。