У меня есть строка, как показано ниже (буквы в примере могут быть цифрами или текстами и могут быть как в верхнем, так и в нижнем регистре или в обоих случаях. Если значение представляет собой предложение, оно должно быть между одинарными котировками):
$string="a,b,c,(d,e,f),g,'h, i j.',k";
Как я могу взорваться, чтобы получить следующий результат?
Array([0]=>"a",[1]=>"b",[2]=>"c",[3]=>"(d,e,f)",[4]=>"g",[5]=>"'h,i j'",[6]=>"k")
Я думаю, что использование регулярных выражений будет быстрым, а также чистым решением. Есть идеи?
EDIT: Это то, что я сделал до сих пор, что очень медленно для строк, имеющих длинную часть между круглыми скобками:
$separator="*"; // whatever which is not used in the string $Pattern="'[^,]([^']+),([^']+)[^,]'"; while(ereg($Pattern,$String,$Regs)){ $String=ereg_replace($Pattern,"'\\1$separator\\2'",$String); } $Pattern="\(([^(^']+),([^)^']+)\)"; while(ereg($Pattern,$String,$Regs)){ $String=ereg_replace($Pattern,"(\\1$separator\\2)",$String); } return $String;
в$separator="*"; // whatever which is not used in the string $Pattern="'[^,]([^']+),([^']+)[^,]'"; while(ereg($Pattern,$String,$Regs)){ $String=ereg_replace($Pattern,"'\\1$separator\\2'",$String); } $Pattern="\(([^(^']+),([^)^']+)\)"; while(ereg($Pattern,$String,$Regs)){ $String=ereg_replace($Pattern,"(\\1$separator\\2)",$String); } return $String;
в$separator="*"; // whatever which is not used in the string $Pattern="'[^,]([^']+),([^']+)[^,]'"; while(ereg($Pattern,$String,$Regs)){ $String=ereg_replace($Pattern,"'\\1$separator\\2'",$String); } $Pattern="\(([^(^']+),([^)^']+)\)"; while(ereg($Pattern,$String,$Regs)){ $String=ereg_replace($Pattern,"(\\1$separator\\2)",$String); } return $String;
Это заменит все запятые между скобками. Затем я могу взорвать его запятыми и заменить $separator
на исходную запятую.
Вы можете выполнить эту работу, используя preg_match_all
$string="a,b,c,(d,e,f),g,'h, i j.',k"; preg_match_all('~\'[^\']++\'|\([^)]++\)|[^,]++~', $string,$result); print_r($result[0]);
Объяснение:
Трюк состоит в том, чтобы сопоставить скобки перед тем ,
~ Pattern delimiter ' [^'] All charaters but not a single quote ++ one or more time in [possessive][1] mode ' | or \([^)]++\) the same with parenthesis | or [^,] All characters but not a comma ++ ~
если у вас более одного разделителя, например, кавычки (одинаковые для открытого и закрытого), вы можете написать свой шаблон, как это, используя группу захвата:
$string="a,b,c,(d,e,f),g,'h, i j.',k,°l,m°,#o,p#,@q,r@,s"; preg_match_all('~([\'#@°]).*?\1|\([^)]++\)|[^,]++~', $string,$result); print_r($result[0]);
объяснение:
(['#@°]) one character in the class is captured in group 1 .*? any character zero or more time in lazy mode \1 group 1 content
С вложенными скобками:
$string="a,b,(c,(d,(e),f),t),g,'h, i j.',k,°l,m°,#o,p#,@q,r@,s"; preg_match_all('~([\'#@°]).*?\1|(\((?>[^()]++|(?-1)?)*\))|[^,]++~', $string,$result); print_r($result[0]);