Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用preg_match_all()获取子组匹配的所有捕获?_Php_Regex_Grammar_Preg Match All - Fatal编程技术网

Php 如何使用preg_match_all()获取子组匹配的所有捕获?

Php 如何使用preg_match_all()获取子组匹配的所有捕获?,php,regex,grammar,preg-match-all,Php,Regex,Grammar,Preg Match All,更新/注意: 我想我可能正在寻找的是在PHP中获得 参考: (仔细阅读:) 我有一个包含可变段数的字符串(简化): 现在,我想匹配段并通过matches数组返回它们: $pattern = '/^(([a-z]+) )+$/i'; $result = preg_match_all($pattern, $subject, $matches); 这将只返回捕获组2的最后一个匹配项:DD 是否有一种方法可以通过一次regex执行检索所有子模式捕获(AA,BB,DD)?preg\u match\u

更新/注意:

我想我可能正在寻找的是在PHP中获得

参考:

(仔细阅读:)


我有一个包含可变段数的字符串(简化):

现在,我想匹配段并通过matches数组返回它们:

$pattern = '/^(([a-z]+) )+$/i';
$result = preg_match_all($pattern, $subject, $matches);
这将只返回捕获组2的最后一个匹配项:
DD

是否有一种方法可以通过一次regex执行检索所有子模式捕获(
AA
BB
DD
)?
preg\u match\u all
是否适用于此

这个问题是一个概括。
$subject
$pattern
都被简化。很自然地,有了这样的总列表,
AA
BB
。。使用其他函数(例如
explode
)或使用
$pattern
的变体更容易提取

但是我特别想问的是,如何返回所有与
preg.
-函数族匹配的子组

对于现实生活中的情况,假设您有多个(嵌套的)级别的不同数量的子模式匹配

例子 这是一个用伪代码来描述一点背景的例子。想象一下:

令牌的常规定义:

   CHARS := [a-z]+
   PUNCT := [.,!?]
   WS := [ ]
$subject
get的标记化基于这些。标记化存储在标记数组(类型、偏移量等)中

然后将该数组转换为字符串,每个标记包含一个字符:

   CHARS -> "c"
   PUNCT -> "p"
   WS -> "s"
因此,现在可以基于令牌流字符串索引上的令牌(而不是字符类等)运行正则表达式。例如

   regex: (cs)?cp
用标点符号表示一组或多组字符

因为我现在可以将自定义标记表示为regex,所以下一步是构建语法。这只是一个例子,这是一种ABNF风格:

   words = word | (word space)+ word
   word = CHARS+
   space = WS
   punctuation = PUNCT
如果我现在将单词的语法编译成一个(标记)正则表达式,我希望自然地拥有每个单词的所有子组匹配

我可以一直编码到这一点。然后我遇到了这样一个问题:分组匹配只包含了最后一个匹配

因此,我可以选择自己为语法创建一个自动机(为了保持语法表达式的通用性,我想阻止它),或者让preg_match在某种程度上为我工作,这样我就可以省掉它

基本上就这些。也许现在可以理解为什么我简化了这个问题


相关的:

    • 编辑

      我不知道你最初要求的是什么。以下是新的解决方案:

      $result = preg_match_all('/[a-z]+/i', $subject, $matches);
      $resultArr = ($result) ? $matches[0] : array();
      
      试试这个:

      preg_match_all("'[^ ]+'i",$text,$n);
      
      $n[0]
      将包含文本中所有非空格字符组的数组

      编辑:带有子组:

      preg_match_all("'([^ ]+)'i",$text,$n);
      
      现在
      $n[1]
      将包含与
      $n[0]
      完全相同的子组匹配项。这其实是没有意义的

      Edit2:嵌套子组示例:

      $test = "Hello I'm Joe! Hi I'm Jane!";
      preg_match_all("/(H(ello|i)) I'm (.*?)!/i",$test,$n);
      
      结果是:

      Array
      (
          [0] => Array
              (
                  [0] => Hello I'm Joe!
                  [1] => Hi I'm Jane!
              )
      
          [1] => Array
              (
                  [0] => Hello
                  [1] => Hi
              )
      
          [2] => Array
              (
                  [0] => ello
                  [1] => i
              )
      
          [3] => Array
              (
                  [0] => Joe
                  [1] => Jane
              )
      
      )
      

      无法提取子模式,因为编写正则表达式的方式只返回一个匹配项(同时使用
      ^
      $
      以及主模式上的
      +

      如果以这种方式编写,您将看到您的子组位于正确的位置:

      $pattern = '/(([a-z]+) )/i';
      
      (这仍然有一组不必要的括号,我只是把它放在那里以示说明)

      怎么样:

      $str = 'AA BB CC';
      $arr = preg_split('/\s+/', $str);
      print_r($arr);
      
      输出:

      (
          [0] => AA
          [1] => BB
          [2] => CC
      )
      

      我可能误解了你的描述。你只是在寻找一组字母之间有空格的模式吗

      // any subject containing words:
      $subject = 'AfdfdfdA BdfdfdB DdD'; 
      $subject = 'AA BB CC';
      $subject = 'Af df dfdA Bdf dfdB DdD';
      
      $pattern = '/(([a-z]+)\s)+[a-z]+/i';
      
      $result = preg_match_all($pattern, $subject, $matches);
      print_r($matches);
      echo "<br/>";
      print_r($matches[0]);  // this matches $subject
      echo "<br/>".$result;
      
      //任何包含单词的主题:
      $subject='AfdfdfdA BdfdfdB DdD';
      $subject='AA BB CC';
      $subject='Af-dfdA-Bdf-dfdB-DdD';
      $pattern='/([a-z]+)\s)+[a-z]+/i';
      $result=preg_match_all($pattern,$subject,$matches);
      打印(匹配项);
      回声“
      ”; 打印($matches[0]);//这与$subject匹配 回显“
      .”$result;
      是否有一种方法可以通过一次正则表达式执行检索所有匹配项(AA、BB、DD)?preg_match_不都适合这样吗

      您当前的正则表达式似乎用于preg_match()调用。请尝试以下方法:

      $pattern = '/[a-z]+/i';
      $result = preg_match_all($pattern, $subject, $matches);
      

      根据评论,我提到的ruby正则表达式:

      sentence = %r{
      (?<subject>   cat   | dog        ){0}
      (?<verb>      eats  | drinks     ){0}
      (?<object>    water | bones      ){0}
      (?<adjective> big   | smelly     ){0}
      (?<obj_adj>   (\g<adjective>\s)? ){0}
      The\s\g<obj_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
      }x
      
      md = sentence.match("The cat drinks water");
      md = sentence.match("The big dog eats smelly bones");
      
      句子=%r{
      (?猫狗){0}
      (?吃|喝){0}
      (?水|骨){0}
      (?大|臭){0}
      (?(\g\s)?){0}
      \s\g\g\s\g\s\g\g\g
      }x
      md=句子匹配(“猫喝水”);
      md=句子.match(“大狗吃臭骨头”);
      

      但我认为您需要一个lexer/parser/tokenizer来在PHP中完成同样的工作-|

      是的,您的权利您的解决方案是使用
      preg\u match\u all
      preg\u match\u all是递归的,因此不要使用以
      ^
      开始,以
      $
      结束,这样
      preg\u match\u all
      将所有找到的模式放在一个数组中

      每对新括号将添加一个新数组,指示不同的匹配项

      使用
      进行可选匹配

      您可以用括号分隔报告的不同模式组
      ()
      ,以请求在新数组中找到并添加一个组(可允许您计算匹配项,或对返回数组中的每个匹配项进行分类)

      需要澄清 让我试着理解你们的问题,以便我的答案和你们的要求相符

    • 你的
      $subject
      不是你想要的东西的好例子

    • 您希望预匹配搜索将您在
      $subject
      中提供的内容分成4个类别单词字符标点空白?那么数字呢

    • 您是否希望返回的匹配项指定匹配项的偏移量

    • Does
      $subject='aa.bb cc.dd EE FFF,GG'更适合真实生活的示例?
      
      $pattern = '/[a-z]+/i';
      $result = preg_match_all($pattern, $subject, $matches);
      
      sentence = %r{
      (?<subject>   cat   | dog        ){0}
      (?<verb>      eats  | drinks     ){0}
      (?<object>    water | bones      ){0}
      (?<adjective> big   | smelly     ){0}
      (?<obj_adj>   (\g<adjective>\s)? ){0}
      The\s\g<obj_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
      }x
      
      md = sentence.match("The cat drinks water");
      md = sentence.match("The big dog eats smelly bones");
      
      Array
      (
          [0] => Array
              (
                  [0] => AA
                  [1] => BB
                  [2] => DD
                  [3] => CD
              )
      
          [1] => Array
              (
                  [0] => A
                  [1] => B
                  [2] => D
                  [3] => C
              )
      
          [2] => Array
              (
                  [0] => A
                  [1] => B
                  [2] => D
                  [3] => D
              )
      
      )