preg_match 包含无限次出现的字符串
preg_match include string with unlimit occurence
我正在尝试创建 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 !');
}
出现一次必须遵守以下格式,两个括号之间的任何字符:(mystring123/)。
整个字符串 ($arg) 是这些事件的集合。
例如
1-此字符串有效 (AAA/)(BBB/)(cc).
2-此字符串无效 (AAA/)xxxx(BBB/)(cc)
该函数工作正常,但我尝试创建的模式不接受多次出现。
我第二次尝试,我改变了模式,但是在执行 preg_match 功能时触发了问题。
#[^\([a-zA-Z0-9_-]+\)$]+#
我需要的是如何解决这个问题,以及如何将后续字符“\”和“/”添加到模式字符串中。
\
在字符转义之前的用法,因此将搜索它。如果您要查找 /
,只需创建一个类似 \/
的模式。如果您要查找 \
,请试试这个:\
。所以 \\/\.\/\
会找到 \/./\
。
通常,您的搜索模式以 php 中的 /
开始和结束。喜欢/[a-zA-Z]\./
要尝试一些新的正则表达式,请尝试此站点:https://regex101.com/
它会解释您输入的每个字符,还会显示它是否仅适用于一个或多个样本。
如果我没记错的话你的 $arg
可能是一个字符串
(AAA/)(BBB/)(cc) 有效,(AAA/)xxxx(BBB/)(cc) 无效。
如果是这种情况,并且您想在 character class 中匹配您接受的字符的出现,您可以将您的
字符和括号,然后将其作为非捕获组重复。
您当前的字符 class [a-zA-Z0-9_-]
不包含正斜杠,因此您可以添加正斜杠以匹配出现的 (AAA/)
。您还可以添加反斜杠。 This page 对转义反斜杠有很好的解释。
您可以将正则表达式更新为:
或使用\w
匹配一个word character匹配[a-zA-Z0-9_]
。这看起来像 [/\w\-]+
那会匹配
^
字符串的开头
(?:
非捕获组
\(
匹配(
[/a-zA-Z0-9_\-]+
您允许的字符在字符集中重复一次或多次
\)
匹配)
)+
关闭非捕获组并重复一次或多次
$
字符串结束
您的代码可能如下所示:
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 !');
}
我已经为这项任务辛勤工作了一段时间,试图设计一种方法将您的全字符串验证与不确定的捕获组结合起来。在尝试了很多 \G
和 lookarounds 的组合后,恐怕无法一次完成。如果 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, 0, 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()
调用的合适替代品,因为它准确输出您将在精简 single-dimensional 数组中寻找的输出,并且使用非常小的可读模式。
*第3个和第4个参数:0
和PREG_SPLIT_NO_EMPTY
分别告诉函数爆炸次数“没有限制”,任何空元素都应该被丢弃(不要做空)
中尾随 cc
)
的元素
我正在尝试创建 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 !');
}
出现一次必须遵守以下格式,两个括号之间的任何字符:(mystring123/)。
整个字符串 ($arg) 是这些事件的集合。
例如
1-此字符串有效 (AAA/)(BBB/)(cc).
2-此字符串无效 (AAA/)xxxx(BBB/)(cc)
该函数工作正常,但我尝试创建的模式不接受多次出现。
我第二次尝试,我改变了模式,但是在执行 preg_match 功能时触发了问题。
#[^\([a-zA-Z0-9_-]+\)$]+#
我需要的是如何解决这个问题,以及如何将后续字符“\”和“/”添加到模式字符串中。
\
在字符转义之前的用法,因此将搜索它。如果您要查找 /
,只需创建一个类似 \/
的模式。如果您要查找 \
,请试试这个:\
。所以 \\/\.\/\
会找到 \/./\
。
通常,您的搜索模式以 php 中的 /
开始和结束。喜欢/[a-zA-Z]\./
要尝试一些新的正则表达式,请尝试此站点:https://regex101.com/
它会解释您输入的每个字符,还会显示它是否仅适用于一个或多个样本。
如果我没记错的话你的 $arg
可能是一个字符串
(AAA/)(BBB/)(cc) 有效,(AAA/)xxxx(BBB/)(cc) 无效。
如果是这种情况,并且您想在 character class 中匹配您接受的字符的出现,您可以将您的 字符和括号,然后将其作为非捕获组重复。
您当前的字符 class [a-zA-Z0-9_-]
不包含正斜杠,因此您可以添加正斜杠以匹配出现的 (AAA/)
。您还可以添加反斜杠。 This page 对转义反斜杠有很好的解释。
您可以将正则表达式更新为:
或使用\w
匹配一个word character匹配[a-zA-Z0-9_]
。这看起来像 [/\w\-]+
那会匹配
^
字符串的开头(?:
非捕获组\(
匹配([/a-zA-Z0-9_\-]+
您允许的字符在字符集中重复一次或多次\)
匹配)
)+
关闭非捕获组并重复一次或多次$
字符串结束
您的代码可能如下所示:
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 !');
}
我已经为这项任务辛勤工作了一段时间,试图设计一种方法将您的全字符串验证与不确定的捕获组结合起来。在尝试了很多 \G
和 lookarounds 的组合后,恐怕无法一次完成。如果 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, 0, 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()
调用的合适替代品,因为它准确输出您将在精简 single-dimensional 数组中寻找的输出,并且使用非常小的可读模式。
*第3个和第4个参数:0
和PREG_SPLIT_NO_EMPTY
分别告诉函数爆炸次数“没有限制”,任何空元素都应该被丢弃(不要做空)
中尾随 cc
)