Php preg_match_all()如何处理字符串?

Php preg_match_all()如何处理字符串?,php,regex,preg-match-all,Php,Regex,Preg Match All,我仍然在学习很多关于PHP的知识,字符串转换是我感兴趣的事情。我以前使用过preg_match来验证电子邮件地址或只是搜索查询 我刚从这篇文章中了解到,我很好奇为什么preg_match_all函数会生成两个字符串,一个是去掉的字符,另一个是所需的输出 从我对函数的理解来看,它使用正则表达式逐个字符地检查字符串,以评估如何处理它。这个正则表达式的结构是否可以绕过第一个数组条目,只生成所需的结果 所以你不必转到另一个线程 $str = 'text^name1^Jony~text^secondnam

我仍然在学习很多关于PHP的知识,字符串转换是我感兴趣的事情。我以前使用过preg_match来验证电子邮件地址或只是搜索查询

我刚从这篇文章中了解到,我很好奇为什么preg_match_all函数会生成两个字符串,一个是去掉的字符,另一个是所需的输出

从我对函数的理解来看,它使用正则表达式逐个字符地检查字符串,以评估如何处理它。这个正则表达式的结构是否可以绕过第一个数组条目,只生成所需的结果

所以你不必转到另一个线程

$str = 'text^name1^Jony~text^secondname1^Smith~text^email1^example-
        free@wpdevelop.com~';

preg_match_all('/\^([^^]*?)\~/', $str, $newStr);

for($i=0;$i<count($newStr[0]);$i++)
{
    echo $newStr[0][$i].'<br>';
}

echo '<br><br><br>';

for($i=0;$i<count($newStr[1]);$i++)
{
    echo $newStr[1][$i].'<br>';
} 
$str='text^name1^Jony~text^secondname1^Smith~text^email1^示例-
free@wpdevelop.com~';
preg_match_all('/\^([^^]*?)\~/',$str,$newStr);

对于($i=0;$i
[0]
包含整个匹配项,而
[1]
仅包含一部分(要提取的部分)。。。 您可以执行
var\u dump($newStr)
来查看数组结构,您会找到它

$str = 'text^name1^Jony~text^secondname1^Smith~text^email1^example-
        free@wpdevelop.com~';

preg_match_all('/\^([^^]*?)\~/', $str, $newStr);

$newStr = $newStr[1];
foreach($newStr as $key => $value)
{
    echo $value."\n"; 
}
这将导致…(奇怪的结果,尚未修改表达式)


这是preg_match和preg_match_all的标准行为——“matched values”数组中的第一个字符串是regex模式捕获的完整字符串。随后的数组值是“捕获组”,其存在取决于regex模式中
()
对的位置/位置

在您的正则表达式中,
/\^([^^]*?)\~/
,完整的匹配字符串将是

^   Jony    ~
|     |     |
^  ([^^]*?) ~   -> $newstr[0] = ^Jony~
                -> $newstr[1] = Jony (due to the `()` capture group).

如前所述,这是预期结果(对于默认的
PREG\u PATTERN\u ORDER
标志)。
$newStr
的第一个条目包含所有完整模式匹配,下一个结果包含第一个子模式的所有匹配(在括号中)依此类推。

preg\u match\u all结果中的第一个数组返回与传递给preg\u match\u all()函数的整个模式相匹配的字符串,在您的例子中是/\^([^]*?)\~/。结果中的后续数组包含模式中括号的匹配项。通过一个示例可能更容易理解:

$string = 'abcdefg';
preg_match_all('/ab(cd)e(fg)/', $string, $matches);
$matches数组将被删除

array(3) {
  [0]=>
  array(1) {
    [0]=>
    string(7) "abcdefg"
  }
  [1]=>
  array(1) {
    [0]=>
    string(2) "cd"
  }
  [2]=>
  array(1) {
    [0]=>
    string(2) "fg"
  }
}
第一个数组将包含整个模式的匹配项,在本例中为“abcdefg”。第二个数组将包含第一组括号的匹配项,在本例中为“cd”。第三个数组将包含第二组括号的匹配项,在本例中为“fg”

这个正则表达式的结构是否可以绕过第一个数组条目,只生成所需的结果

绝对正确。使用。此正则表达式:

preg_match_all('/(?<=\^)[^^]*?(?=~)/', $str, $newStr);

每当你在想象preg_match_的功能时遇到问题时,你都应该使用一个类似


这将实时显示结果,您可以配置结果顺序、元指令、偏移捕获等更多内容。

输出将始终包含整个匹配项以及表达式中每个捕获组的条目。这不是答案,但值得注意的是,
PREG\u SET\u order
标志,它将urn是一个更简单的结果列表。虽然无法删除完整匹配的
[0]
数组项,但可以使用正则表达式中的
\K
删除其内容。啊,我理解,所以它做的第一件事是查找以w/^开头、以~结尾的文本,然后在()在“^减去~”之后获取所有内容。我想好奇占了上风,如果[^^]*?告诉它抓取“^”之后的文本,为什么它不抓取“~”?它抓取了,但是
~
不在您的捕获组中,所以它只会出现在
[0]中可以将整个ReX模式视为一个捕获组本身,以便虚拟捕获被存储在<代码>(0)< /代码>中,然后捕获您显式创建的“<代码>())/代码>进入[ 1 ]、[ 2 ]等…<代码> [^ ^ ] * /<代码>转换为“不是^ ^(^ ^))的多个字符(*,‘0’或以上))。,以非贪婪的方式(?)。
preg_match_all('/(?<=\^)[^^]*?(?=~)/', $str, $newStr);
Array
(
    [0] => Array
        (
            [0] => Jony
            [1] => Smith
            [2] => example-free@wpdevelop.com
        )

)