PHP preg_split()模式

时间:2018-07-29 22:16:23

标签: php pcre preg-split

我需要使用preg_split()查找PCRE模式的帮助。

我正在使用以下正则表达式模式根据字符串的起始3个字符代码和分号来拆分字符串。该模式在Javascript中可以正常工作,但是现在我需要在PHP中使用该模式。我尝试了preg_split(),但又变回了垃圾。

//每个组将从一个三个字母的代码开始,具有三个由分号分隔的段。字符串不会以分号结尾。

// Pseudocode    
string_to_split = "AAA;RED;111;BBB;BLUE;22;CCC;GREEN;33;DDD;WHITE;44"

// This works in JS  
// https://regex101.com  
$pattern = "/[AAA|BBB|CCC|DDD][^;]*;[^;]*[;][^;]*/gi";

Match 1  
Full match  0-11    `AAA;RED;111`  
Match 2  
Full match  12-23   `BBB;BLUE;22`  
Match 3  
Full match  24-36   `CCC;GREEN;33`  
Match 4  
Full match  37-49   `DDD;WHITE;44`  

$pattern = "/[AAA|BBB|CCC|DDD][^;]*;[^;]*[;][^;]*/";  
$split = preg_split($pattern, $string_to_split);

returns

array(5)  
    0:""  
    1:";"  
    2:";"  
    3:";"  
    4:""  

3 个答案:

答案 0 :(得分:1)

我对您的模式进行了一些修改,并为preg_split添加了一些标志。

PREG_SPLIT_NO_EMPTY标志将从结果中排除空匹配项,PREG_SPLIT_DELIM_CAPTURE将在结果中包含捕获的值。

$split = preg_split('/([abcd]{3};[^;]+;\d+);?/i', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);

结果:

Array
(
    [0] => AAA;RED;111
    [1] => BBB;BLUE;22
    [2] => CCC;GREEN;33
    [3] => DDD;WHITE;44
)

或者更合适的是,您可以将preg_match_all用于以下模式。

preg_match_all('/([abcd]{3};[^;]+;\d+);?/i', $string, $matches);

print_r($matches[0]);

结果:

Array
(
    [0] => AAA;RED;111
    [1] => BBB;BLUE;22
    [2] => CCC;GREEN;33
    [3] => DDD;WHITE;44
)

答案 1 :(得分:1)

根据您对答案的一些评论中的其他信息,我将答案更新为非常特定于您的源格式。

您可能想要这样的东西:

$subject = "AAA;RED;111;AAA;Oh my dog;12.34;AAA;Oh Long John;.4556;BBB;Oh Long Johnson;1.2323;BBB;Oh Don Piano;.33;CCC;Why I eyes ya;1.445;CCC;All the live long day;2.3343;DDD;Faith Hilling;.89";

$pattern = '/(?<=;|^)(AAA|BBB|CCC|DDD);([^;]*);((?:\d*\.)?\d+)(?=;|$)/';
preg_match_all($pattern, $subject,$matches);
var_dump($matches);

给你

array (size=4)
  0 =>
    array (size=8)
      0 => string 'AAA;RED;111' (length=11)
      1 => string 'AAA;Oh my dog;12.34' (length=19)
      2 => string 'AAA;Oh Long John;.4556' (length=22)
      3 => string 'BBB;Oh Long Johnson;1.2323' (length=26)
      4 => string 'BBB;Oh Don Piano;.33' (length=20)
      5 => string 'CCC;Why I eyes ya;1.445' (length=23)
      6 => string 'CCC;All the live long day;2.3343' (length=32)
      7 => string 'DDD;Faith Hilling;.89' (length=21)
  1 =>
    array (size=8)
      0 => string 'AAA' (length=3)
      1 => string 'AAA' (length=3)
      2 => string 'AAA' (length=3)
      3 => string 'BBB' (length=3)
      4 => string 'BBB' (length=3)
      5 => string 'CCC' (length=3)
      6 => string 'CCC' (length=3)
      7 => string 'DDD' (length=3)
  2 =>
    array (size=8)
      0 => string 'RED' (length=3)
      1 => string 'Oh my dog' (length=9)
      2 => string 'Oh Long John' (length=12)
      3 => string 'Oh Long Johnson' (length=15)
      4 => string 'Oh Don Piano' (length=12)
      5 => string 'Why I eyes ya' (length=13)
      6 => string 'All the live long day' (length=21)
      7 => string 'Faith Hilling' (length=13)
  3 =>
    array (size=8)
      0 => string '111' (length=3)
      1 => string '12.34' (length=5)
      2 => string '.4556' (length=5)
      3 => string '1.2323' (length=6)
      4 => string '.33' (length=3)
      5 => string '1.445' (length=5)
      6 => string '2.3343' (length=6)
      7 => string '.89' (length=3)

起始标记应出现在字符串的开头或在分号后的中间,因此我们在后面进行查找,以查找起始或分号:

(?<=;|^)

我们正在寻找AAA,BBB,CCC或DDD的替代品并捕获它:

(AAA|BBB|CCC|DDD)

在分号之后,我们寻找除分号外的任何字符。量词*表示0或更多时间。如果需要至少1,请使用+

;([^;]*)

在下一个分号之后,寻找一个数字。必须拆分此任务以适合有效的格式:我们首先查找0或多个数字,后跟一个点:

(?:\d*\.)?

其中(?:)表示非捕获组。

我们在后面寻找至少一位数字:\d+

我们要在搜索的分号后使用括号捕获数字的两个部分:

;((?:\d*\.)?\d+)

此匹配“ 1234”,“。1234”,“ 1.234”,“ 12.34”,“ 123.4”,但匹配“ 1234。”,“ 1.2.3”

最后,我们希望此操作在分号或字符串结尾之前立即发生。因此,我们进行了前瞻:

(?=;|$)

先行者和回头客不在捕获结果的后面或之前。

答案 2 :(得分:0)

您不想分割字符串而是匹配元素,请使用preg_match_all:

$str = "AAA;RED;111;AAA;Oh my dog;2.34;AAA;Oh Long John;.4556;BBB;Oh Long Johnson;1.2323;BBB;Oh Don Piano;.33;CCC;Why I eyes ya;1.445;CCC;All the live long day;2.3343;DDD;Faith Hilling;.89";
$res = preg_match_all('/(?:AAA|BBB|CCC|DDD);[^;]*;[^;]*;?/', $str, $m);
print_r($m[0]);

输出:

Array
(
    [0] => AAA;RED;111;
    [1] => AAA;Oh my dog;2.34;
    [2] => AAA;Oh Long John;.4556;
    [3] => BBB;Oh Long Johnson;1.2323;
    [4] => BBB;Oh Don Piano;.33;
    [5] => CCC;Why I eyes ya;1.445;
    [6] => CCC;All the live long day;2.3343;
    [7] => DDD;Faith Hilling;.89
)

说明:

/                       : regex delimiter
  (?:AAA|BBB|CCC|DDD)   : non capture group AAA or BBB or CCC or DDD
  ;                     : a semicolon
  [^;]*                 : 0 or more any character that is not a semicolon
  ;                     : a semicolon
  [^;]*                 : 0 or more any character that is not a semicolon
  ;?                    : optional semicolon
/                       : regex delimiter