Php 正则表达式匹配2-20个字母数字字符,允许字符串中任意位置使用一个连字符

Php 正则表达式匹配2-20个字母数字字符,允许字符串中任意位置使用一个连字符,php,regex,Php,Regex,我正在努力学习如何使用preg_match。我希望只允许用户使用2-20个字符(可以包含a-zA-Z0-9)之间的用户名注册 现在,我迷路的棘手部分是,我希望他们能够在用户名中的任何位置包含一个连字符 -Brad = TRUE --Brad = FALSE B-Rad = TRUE -布拉德=真 --布拉德=错 B-Rad=真 您可以将preg_match用于: \w*-?\w* 它将确保存在一个连字符,但也将只匹配一个连字符。您还可以使用: (\w*-?\w+)|(\w+-?\w*)

我正在努力学习如何使用preg_match。我希望只允许用户使用2-20个字符(可以包含a-zA-Z0-9)之间的用户名注册

现在,我迷路的棘手部分是,我希望他们能够在用户名中的任何位置包含一个连字符

-Brad = TRUE --Brad = FALSE B-Rad = TRUE -布拉德=真 --布拉德=错 B-Rad=真
您可以将preg_match用于:

\w*-?\w*
它将确保存在一个连字符,但也将只匹配一个连字符。您还可以使用:

(\w*-?\w+)|(\w+-?\w*)
避免只匹配连字符。或者,您可以检查匹配的长度是否大于1

你说可以,所以我认为连字符不是必需的。如果是,请卸下?在正则表达式中

如果您计划在一个句子中进行匹配,您可以使用带\w+部分的分词(\b)。如果要在修剪过的字符串上使用此选项,请在开头和结尾分别添加^和$,以避免将
--Bra-d
匹配为true

^[a-zA-Z0-9]*\-?[a-zA-Z0-9]*$ 
是正则表达式吗


编辑:长度的快速解决方案:使用第二个preg_匹配与
^.{2,20}$

您可以一步一步地建立此匹配。您需要由2-20个特定字符组成的用户名:

^[a-zA-Z0-9]{2,20}$
现在,您希望在其中的某个位置允许一个
-
字符(技巧部分):

-
字符只有在字符串末尾没有紧跟另一个
-
字符时才允许使用:

[-](?=[^-]*$)
这就是所谓的先行断言。结合一个替代项,正则表达式完成以下操作:

^(?:[a-zA-Z0-9]|[-](?=[^-]*$)){2,20}$
与给出的其他答案相比,此答案尊重您的长度规格。

以下是我的做法:

if(预匹配(
“/#匹配字母数字的pwd,允许一个可选破折号。
^#锚定至管柱起点。
(?=.{2,20}\z)#断言长度为2到20个字符。
[a-zA-Z0-9]*#破折号前的α数值为零或更多。
([a-zA-Z0-9]*)?#可选破折号和更多字母编号。
\z#锚定在绳子的末端。
/x',$text)){
#成功的比赛
}否则{
#匹配尝试失败
}

我希望只允许用户使用一个连字符。它们不必有连字符。我想将它们限制在用户名长度为2-20的范围内,只有将包含的其他字符可以是a-zA-Z0-9。这些模式是否拒绝使用多个连字符?这一切都是允许的。我想在用户名中的任何位置将它们限制为字母数字加上1个连字符。是的,这是可行的,但我如何将其限制为2-20个字符?感谢您的编辑,我将有一个游戏,让php函数保存我继续在以下位置键入:)@Bradley Roberts随时。我认为最好使用
strlen
进行长度验证检查正则表达式中的长度,请参见。使用正则表达式检查字符串长度?真的吗?哇谢谢你的回答。你也解释得很好,我正准备放弃尝试,接受使用两个赛前状态。@Bradley Roberts:不客气。你写了你想学的东西,而你问题中的模式并不那么明显,所以有一些东西需要修补;)祝你的正则表达式进展顺利,用这种语言思考需要一些时间,但它真的很强大。您还可以尝试通过回答此处弹出的正则表达式问题来改进,因为其他答案通常都有一些需要学习的地方。