preg_match包含无限制出现的字符串

时间:2018-03-12 13:23:39

标签: php regex preg-match

我尝试使用模式创建preg_match函数,以验证未来字符串的无限制出现。这是我的功能:

if(! preg_match_all("#^\([a-zA-Z0-9_-]+\)$#", $arg, $matches, PREG_OFFSET_CAPTURE)){
    var_dump($matches);
    throw new \Exception('The simple pattern "'.$arg.'" is not valid !');
}

一次出现必须遵循两个括号之间的任何charchters的以下格式:(mystring123 /)。 整个字符串($ arg)是这些事件的集合 例如
1 - 此字符串有效(AAA /)(BBB /)(cc) 2 - 此字符串无效(AAA /)xxxx(BBB /)(cc)

该函数正常工作,但我尝试创建的模式不会接受多次出现。

我的第二次尝试,我改变了模式但是在执行preg_match函数时已经触发了问题。

#[^\([a-zA-Z0-9_-]+\)$]+#

我需要的是如何解决这个问题,以及如何添加模式字符串以及追随者" \"和" /"。

3 个答案:

答案 0 :(得分:2)

我已经忙于这项任务一段时间了,试图设计一种方法,将你的全字符串验证与不确定的捕获组合起来。在尝试了\G和外观的许多组合之后,恐怕不能一次完成。如果php允许可变宽度的外观,我想我可以,但唉,它们不可用。

我能提供的是一个删除了不必要的“东西”的过程。

代码:(Demo

$strings = ["(AAA/)(BBB/)(cc)", "(AAA/)xxxx(BBB/)(cc)"];

foreach ($strings as $string) {
    if (!preg_match('~^(?:\([\w\\/-]+\))+$~', $string)) {
        echo "The simple pattern $string is not valid!";
        // throw new \Exception("The simple pattern $string is not valid!");
    } else {
        var_export(preg_split('~\)\K~', $string, null, PREG_SPLIT_NO_EMPTY));
    }
    echo "\n";
}

输出:

array (
  0 => '(AAA/)',
  1 => '(BBB/)',
  2 => '(cc)',
)
The simple pattern (AAA/)xxxx(BBB/)(cc) is not valid!

模式#1细分:

~              #pattern delimiter
^              #start of string anchor
(?:            #start of non-capturing group
  \(           #match one opening parenthesis
  [\w\\/-]+    #greedily match one or more of the following characters: a-z, A-Z, 0-9, underscores, backslashes, slashes, and hyphens
  \)           #match one closing parenthesis
)              #end of non-capturing group
+              #allow one or more occurrences of the non-capturing group
$              #end of string anchor
~              #pattern delimiter

模式#2细分:

~              #pattern delimiter
\)             #match one closing parenthesis
\K             #restart the fullstring match (forget/release previously matched character(s))
~              #pattern delimiter

模式#2的效果是找到每个右括号并“爆炸”在右括号后面的零宽度位置上的字符串。 \K确保没有角色在爆炸中成为伤亡者。

if条件不需要调用preg_match_all(),因为在您从^$进行验证时,只能有一个匹配的字符串。声明一个包含“匹配”的变量是没有意义的(就像PREG_OFFSET_CAPTURE) - 如果匹配,它将是整个输入字符串,所以只要你想要它就可以使用该值。

preg_split()preg_match_all()调用的合适替代品,因为它准确输出您将在精简的单维数组中搜索的输出并使用非常小的可读模式。 *第3和第4个参数:nullPREG_SPLIT_NO_EMPTY分别告诉函数爆炸次数“无限制”,并且应丢弃任何空元素(不要空跟踪)

cc元素

答案 1 :(得分:1)

如果我没弄错,你的value=可能是一个字符串 (AAA /)(BBB /)(cc)有效且(AAA /)xxxx(BBB /)(cc)无效。

如果是这种情况,并且您希望在character class中匹配您接受的字符的匹配项,则可以对 字符和括号,然后重复它作为非捕获组。

您当前的字符类$arg不包含正斜杠,因此您可以添加该字符以匹配[a-zA-Z0-9_-]之类的匹配项。您也可以添加反斜杠。 This page对逃避反斜杠有一个很好的解释。

您可以将正则表达式更新为:

^(?:\([/a-zA-Z0-9_\\-]+\))+$

或使用(AAA/)匹配与\w匹配的word character。这看起来像[a-zA-Z0-9_]

匹配

  • [/\w\\-]+字符串的开头
  • ^非捕获组
    • (?:匹配(
    • \(字符集中允许的字符重复一次或多次
    • [/a-zA-Z0-9_\\-]+匹配)
  • \)关闭非捕获组并重复一次或多次
  • )+字符串的结尾

您的代码可能如下所示:

$

Demo php

答案 2 :(得分:-1)

在角色转义之前使用\,因此会搜索它。如果您查找/,请创建类似\/的模式。如果您查找\,请尝试以下方法:\\。因此\\\/\.\/\\会找到\/./\。 通常,您在php中使用/开始和结束搜索模式。与/[a-zA-Z]\./

一样

要试用一些新的正则表达式,请尝试以下网站:https://regex101.com/

它将解释您输入的每个字符,并显示它是否仅适用于一个或多个样本。