正则表达式 - 在匹配中忽略字符串的某些部分

时间:2013-06-06 19:44:10

标签: regex preg-match-all

这是我的字符串:

address='St Marks Church',notes='The North East\'s premier...'

我用match_all抓取各个部分的正则表达式是

'/(address|notes)='(.+?)'/i'

结果如下:

  

地址=> St Marks Church
notes =>东北地区\

如何让它忽略笔记的\'字符?

3 个答案:

答案 0 :(得分:5)

不确定你是否用heredoc或双引号包装你的字符串,但是不那么贪心的方法:

$str4 = 'address="St Marks Church",notes="The North East\'s premier..."';
preg_match_all('~(address|notes)="([^"]*)"~i',$str4,$matches);
print_r($matches);

输出

Array
(
    [0] => Array
        (
            [0] => address="St Marks Church"
            [1] => notes="The North East's premier..."
        )

    [1] => Array
        (
            [0] => address
            [1] => notes
        )

    [2] => Array
        (
            [0] => St Marks Church
            [1] => The North East's premier...
        )

)

另一种使用preg_split的方法:

//split the string at the comma
//assumes no commas in text
$parts = preg_split('!,!', $string);
foreach($parts as $key=>$value){
    //split the values at the = sign
    $parts[$key]=preg_split('!=!',$value);
    foreach($parts[$key] as $k2=>$v2){
        //trim the quotes out and remove the slashes
        $parts[$key][$k2]=stripslashes(trim($v2,"'"));
    }
}

输出如下:

Array
(
    [0] => Array
        (
            [0] => address
            [1] => St Marks Church
        )

    [1] => Array
        (
            [0] => notes
            [1] => The North East's premier...
        )

)

超慢的旧skool方法:

$len = strlen($string);
$key = "";
$value = "";
$store = array();
$pos = 0;
$mode = 'key';
while($pos < $len){
  switch($string[$pos]){
    case $string[$pos]==='=':
        $mode = 'value';
        break;
    case $string[$pos]===",":
        $store[$key]=trim($value,"'");
        $key=$value='';
        $mode = 'key';
        break;
    default:
        $$mode .= $string[$pos];
  }

  $pos++;
}
        $store[$key]=trim($value,"'");

答案 1 :(得分:1)

您应该匹配一个前面没有反斜杠的结尾引用:

(address|notes)='(.*?)[^\\]'

这个[^\\]强制紧跟'字符前面的字符只是反斜杠。

答案 2 :(得分:1)

由于您已发布使用match_all并且个人资料中的热门标记为phpwordpress,因此我认为假设您使用的是{{1}用php。

以下模式将匹配构建所需关联数组所需的子字符串:

生成全字符串匹配和1个捕获组的模式:

  1. preg_match_all()(166步,demo link
  2. /(address|notes)='\K(?:\\\'|[^'])*/(218步,demo link
  3. 生成2个捕获组的模式:

    1. /(address|notes)='\K.*?(?=(?<!\\)')/(168步,demo link
    2. /(address|notes)='((?:\\\'|[^'])*)/(209步,demo link
    3. 代码:(Demo

      /(address|notes)='(.*?(?<!\\))'/

      输出:

      $string="address='St Marks Church',notes='The North East\'s premier...'";
      
      if(preg_match_all("/(address|notes)='\K(?:\\\'|[^'])*/",$string,$out)){
          $result=array_combine($out[1],$out[0]);
      }
      var_dump($result);
      
      echo "\n---\n";
      
      if(preg_match_all("/(address|notes)='((?:\\\'|[^'])*)/",$string,$out,PREG_SET_ORDER)){
          $result=array_combine(array_column($out,1),array_column($out,2));
      }
      var_dump($result);
      

      模式#1和#3使用替代方法允许非撇号字符或撇号前面没有反斜杠。

      模式#2和#4(使用php demo实现时需要额外的反斜杠)使用外观来确保前面加上反斜杠的撇号不会结束匹配。

      一些注意事项:

      • 使用捕获组,替代方案和外观会降低模式效率。限制使用这些组件将提高性能。使用否定字符类通常可以提高性能。

      • 在尝试减少捕获组时,使用array(2) { ["address"]=> string(15) "St Marks Church" ["notes"]=> string(28) "The North East\'s premier..." } --- array(2) { ["address"]=> string(15) "St Marks Church" ["notes"]=> string(28) "The North East\'s premier..." } (重新启动全字符串匹配)很有用,它会减小输出数组的大小。