PHP preg_match_all() - 我的正则表达式有什么问题?

发布于 2024-10-26 11:04:29 字数 3274 浏览 1 评论 0原文

这是一个示例字符串:

---------
SAY WHAAAAT
MEDICS:
CREW ID: PMD205304 CREW MEMBER ROLE: PRIMARY PATIENT CAREGIVER CREW MEMBER LEVEL: EMT-PARAMEDIC
CREW ID: EMT530755 CREW MEMBER ROLE: OTHER CREW MEMBER LEVEL: EMT-BASIC

这是执行 preg_match_all() 并将 $matches 数组转换为更可用的数组的函数:

      private function getMedics(){
        if(isset($this->record->elements["E04"])){
              //REGEX:
              $ptn = "/(?:CREW ID: (.+?) )*(?:CREW MEMBER ROLE: (.+?)\s+)*(?:CREW MEMBER LEVEL: (.+))?\n/";
              $str = $this->record->incidentRow['Narrative']; //Column where medic info is stored in CodeZoneIncidents table
              preg_match_all($ptn,$str,$matches);
              foreach($matches as $key => $val){
                  foreach($matches[$key] as $key2 => $val2){
                      if(trim($val2) != ""){
                          $tmp[$key2]['ID'] = $matches[1][$key2];
                          $tmp[$key2]['role'] = $matches[2][$key2];
                          $tmp[$key2]['level'] = $matches[3][$key2];
                      }
                  }
              }
              $ii = 0;
              foreach($tmp as $key => $val){
                  $CZMedics[$ii]['ID'] = $tmp[$key]['ID'];
                  $CZMedics[$ii]['role'] = $tmp[$key]['role'];
                  $CZMedics[$ii]['level'] = $tmp[$key]['level'];
                  $ii++;
              } //REGEX pattern

              $iterations = $this->eleQTY($this->record->elements["E04"]); //Return how many E04 there are
              for($i=0; $i<$iterations; $i++){
                    //[E04][0] if there are multiples:
                    $tmpEle = (isset($this->record->elements["E04"][$i])?$this->record->elements["E04"][$i]:$this->record->elements["E04"]);
                    //Populate Actual values:
                    if(isset($tmpEle["E04_01"]->code)){
                          $tmpEle["E04_01"]->actual = fncIsSet($CZMedics[$i]['ID']); //Medic ID
                          $tmpEle["E04_01"]->CZCellName = "Narrative_Box"; //CZPopUp Box
                    }
                    if(isset($tmpEle["E04_02"]->code)){
                          $tmpEle["E04_02"]->actual = fncIsSet($CZMedics[$i]['role']); //Role
                          $tmpEle["E04_02"]->CZCellName = "Narrative_Box"; //CZPopUp Box
                    }
                    if(isset($tmpEle["E04_03"]->code)){
                          $tmpEle["E04_03"]->actual = fncIsSet($CZMedics[$i]['level']); //Level
                          $tmpEle["E04_03"]->CZCellName = "Narrative_Box"; //CZPopUp Box
                    }
              }
              echo "<pre style='display:none;'>!!!";
              print_r($CZMedics);
              echo "</pre>";
        }       
  }

这​​是生成的数组:)

Array
(
    [0] => Array
        (
            [ID] => PMD205304
            [role] => PRIMARY PATIENT CAREGIVER
            [level] => EMT-PARAMEDIC
        )

[1] => Array
    (
        [ID] => 
        [role] => 
        [level] => 
    )

所以

我想要的是返回所有医疗信息( ID、角色和级别),但我不希望该模式依赖于任何一项信息 - 因此如果存在任何一个数据点,它应该返回医生。

Here is a sample string:

---------
SAY WHAAAAT
MEDICS:
CREW ID: PMD205304 CREW MEMBER ROLE: PRIMARY PATIENT CAREGIVER CREW MEMBER LEVEL: EMT-PARAMEDIC
CREW ID: EMT530755 CREW MEMBER ROLE: OTHER CREW MEMBER LEVEL: EMT-BASIC

And this is the function that performs the preg_match_all() and translates the $matches array into a more usable array:

      private function getMedics(){
        if(isset($this->record->elements["E04"])){
              //REGEX:
              $ptn = "/(?:CREW ID: (.+?) )*(?:CREW MEMBER ROLE: (.+?)\s+)*(?:CREW MEMBER LEVEL: (.+))?\n/";
              $str = $this->record->incidentRow['Narrative']; //Column where medic info is stored in CodeZoneIncidents table
              preg_match_all($ptn,$str,$matches);
              foreach($matches as $key => $val){
                  foreach($matches[$key] as $key2 => $val2){
                      if(trim($val2) != ""){
                          $tmp[$key2]['ID'] = $matches[1][$key2];
                          $tmp[$key2]['role'] = $matches[2][$key2];
                          $tmp[$key2]['level'] = $matches[3][$key2];
                      }
                  }
              }
              $ii = 0;
              foreach($tmp as $key => $val){
                  $CZMedics[$ii]['ID'] = $tmp[$key]['ID'];
                  $CZMedics[$ii]['role'] = $tmp[$key]['role'];
                  $CZMedics[$ii]['level'] = $tmp[$key]['level'];
                  $ii++;
              } //REGEX pattern

              $iterations = $this->eleQTY($this->record->elements["E04"]); //Return how many E04 there are
              for($i=0; $i<$iterations; $i++){
                    //[E04][0] if there are multiples:
                    $tmpEle = (isset($this->record->elements["E04"][$i])?$this->record->elements["E04"][$i]:$this->record->elements["E04"]);
                    //Populate Actual values:
                    if(isset($tmpEle["E04_01"]->code)){
                          $tmpEle["E04_01"]->actual = fncIsSet($CZMedics[$i]['ID']); //Medic ID
                          $tmpEle["E04_01"]->CZCellName = "Narrative_Box"; //CZPopUp Box
                    }
                    if(isset($tmpEle["E04_02"]->code)){
                          $tmpEle["E04_02"]->actual = fncIsSet($CZMedics[$i]['role']); //Role
                          $tmpEle["E04_02"]->CZCellName = "Narrative_Box"; //CZPopUp Box
                    }
                    if(isset($tmpEle["E04_03"]->code)){
                          $tmpEle["E04_03"]->actual = fncIsSet($CZMedics[$i]['level']); //Level
                          $tmpEle["E04_03"]->CZCellName = "Narrative_Box"; //CZPopUp Box
                    }
              }
              echo "<pre style='display:none;'>!!!";
              print_r($CZMedics);
              echo "</pre>";
        }       
  }

And here is the resulting array:

Array
(
    [0] => Array
        (
            [ID] => PMD205304
            [role] => PRIMARY PATIENT CAREGIVER
            [level] => EMT-PARAMEDIC
        )

[1] => Array
    (
        [ID] => 
        [role] => 
        [level] => 
    )

)

So what I want is to return all of the medic info (ID, role & level), but I don't want the pattern to be dependent on any one piece of info being there - So it should return the medic if any one of those data points are present.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的奇迹 2024-11-02 11:04:32

这应该可以解决问题:

^CREW ID:(.*) CREW MEMBER ROLE:(.*) CREW MEMBER LEVEL:(.*)$

至少它适用于您提供的示例。但是“.+?”字段之间的星号“*”可能意味着您希望它们是可选的或者您希望允许多个。所以也许您需要提供更多示例...

顺便说一句:如果您想确保该行完全匹配,请使用 ^$。并激活允许 ^$ 匹配换行符的选项。我不想使用“\n”

This should do the trick:

^CREW ID: (.*) CREW MEMBER ROLE: (.*) CREW MEMBER LEVEL: (.*)$

at least it works for the example you provided. But the ".+?" and stars "*" between the fields could mean you want them to be optional or you want to allow more than one. So maybe you need to provide more examples...

BTW: If you want to ensure the line matches exactly use ^$. and to activate the option that allows ^$ to match line breaks. I#d rather not use "\n"

离线来电— 2024-11-02 11:04:30

您几乎可以通过使用命名捕获组来消除手动循环分配:

preg_match_all('~^(?=CREW)(CREW ID: (?P<id>\w+))?\s*(CREW MEMBER ROLE: (?<role>.*?))?\s*(CREW MEMBER LEVEL: (?<level>.*?))?$~mi', $text, $match, PREG_SET_ORDER);

这将导致许多无关的条目,但是 [id][role][level] 已经被分离出来(当然你可以再次添加 ?: 以减少混乱):

[0] => Array
    (
        [0] => CREW ID: PMD205304 CREW MEMBER ROLE: PRIMARY PATIENT CAREGIVER CREW MEMBER LEVEL: EMT-PARAMEDIC
        [1] => CREW ID: PMD205304
        [id] => PMD205304
        [2] => PMD205304
        [3] =>  CREW MEMBER ROLE: PRIMARY PATIENT CAREGIVER
        [role] => PRIMARY PATIENT CAREGIVER
        [4] => PRIMARY PATIENT CAREGIVER
        [5] =>  CREW MEMBER LEVEL: EMT-PARAMEDIC
        [level] => EMT-PARAMEDIC
        [6] => EMT-PARAMEDIC
    )

You can pretty much eliminate the manual loop assignment by using named capture groups:

preg_match_all('~^(?=CREW)(CREW ID: (?P<id>\w+))?\s*(CREW MEMBER ROLE: (?<role>.*?))?\s*(CREW MEMBER LEVEL: (?<level>.*?))?$~mi', $text, $match, PREG_SET_ORDER);

This will result in a many extranous entries, but [id] and [role] and [level] are already separated out (of course you can add ?: again to reduce the clutter):

[0] => Array
    (
        [0] => CREW ID: PMD205304 CREW MEMBER ROLE: PRIMARY PATIENT CAREGIVER CREW MEMBER LEVEL: EMT-PARAMEDIC
        [1] => CREW ID: PMD205304
        [id] => PMD205304
        [2] => PMD205304
        [3] =>  CREW MEMBER ROLE: PRIMARY PATIENT CAREGIVER
        [role] => PRIMARY PATIENT CAREGIVER
        [4] => PRIMARY PATIENT CAREGIVER
        [5] =>  CREW MEMBER LEVEL: EMT-PARAMEDIC
        [level] => EMT-PARAMEDIC
        [6] => EMT-PARAMEDIC
    )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文