0

我正在尝试在 PHP 中创建一个正则表达式。我可以让它用其他语言工作,但不能用 PHP。

我想验证数组中的项目名称

  • 它们可以包含大小写字母、数字、下划线和连字符。
  • 它们可以包含=>精确的字符串,而不是单独的字符。
  • 他们不能以=>.
  • 他们不能以=>.

我当前的代码:

$regex = '/^[a-zA-Z0-9-_]+$/';    // contains A-Z a-z 0-9 - _
//$regex = '([^=>]$)';  // doesn't end with =>
//$regex = '~.=>~';  // doesn't start  with =>

if (preg_match($regex, 'Field_name_true2')) {
    echo 'true';
} else {
    echo 'false';
};
// Field=>Value-True
// =>False_name
//Bad_name_2=>
4

4 回答 4

3

使用负面环视。开头的负前瞻(?!=>)禁止以 开头=>,结尾的负向后查找(?<!=>)禁止以 结尾=>

^(?!=>)(?:[a-zA-Z0-9-_]+(=>)?)+(?<!=>)$

演示

于 2021-08-29T03:44:41.177 回答
3

这里绝对不需要环视。

锚点和可选组就足够了。

演示

/^[\w-]+(?:=>[\w-]+)?$/
        ^^^^^^^^^^^^^-- this whole non-capturing group is optional

这允许完全由 . 组成[0-9a-zA-Z-]或拆分 ONCE 的完整字符串=>

非捕获组可能出现零次或一次。

换句话说,=>可能出现在一个或多个[\w-]字符之后,但如果确实出现,则必须紧跟一个或多个[\w-]字符,直到字符串的末尾。


为了涵盖问题要求中的一些歧义:

  • 如果foo=>bar=>bam有效,则使用/^[\w-]+(?:=>[\w-]+)*$/which 将?(零或一)替换为*(零或更多)。

  • 如果foo=>=>bar有效,则使用/^[\w-]+(?:(?:=>)+[\w-]+)*$/which 替换=>(必须出现一次)与(?:=>)+(子字符串必须出现一次或多次)。

于 2021-08-29T10:39:58.593 回答
1

对于示例数据,您可以使用

^[a-zA-Z0-9_-]+=>[a-zA-Z0-9_-]+$

模式匹配:

  • ^字符串的开始
  • [a-zA-Z0-9_-]+匹配任何列出的范围或字符的 1 次以上(不能以 => 开头)
  • =>从字面上匹配
  • [a-zA-Z0-9_-]+再次匹配任何列出的范围或字符的 1 次以上
  • $字符串结束

正则表达式演示

如果要允许可选空格:

^\h*[a-zA-Z0-9_-]+\h*=>\h*[a-zA-Z0-9_-]+\h*$

正则表达式演示

注意可以[a-zA-Z0-9_-]写成[\w-]

于 2021-08-29T08:05:49.930 回答
1

好吧,你的字符范围等于\w,所以你可以使用

^(?!=>)(?:(?!=>$)(?:[-\w]|=>))+$

此构造使用“tempered greedy token”,请参阅regex101.com 上的演示


更闪亮、更复杂、更重要的是,您可以使用子例程,如下所示:

(?(DEFINE)
    (?<chars>[-\w])             # equals to A-Z, a-z, 0-9, _, -
    (?<af>=>)                   # "arrow function"
    (?<item>
        (?!(?&af))              # no af at the beginning
        (?:(?&af)?(?&chars)++)+
        (?!(?&af))              # no af at the end
    )
)
^(?&item)$

在 regex101.com 上查看另一个演示

于 2021-08-29T09:03:39.103 回答