Я хочу разделить запросы mysql из формата экспорта phpmyadmin. Каждый запрос будет разделен на «;» но не может использовать взрыв, потому что ";" может быть где угодно и в полевом значении. Ниже приведен один пример.
insert into wp_options (option_id, blog_id, option_name, option_value, autoload) values (201, 0, "tadv_btns2", "a:21:{i:0;s:14:\"fontsizeselect\";i:1;s:12:\"formatselect\";i:2;s:9:\"pastetext\";i:3;s:9:\"pasteword\";i:4;s:12:\"removeformat\";i:5;s:9:\"separator\";i:6;s:7:\"charmap\";i:7;s:5:\"print\";i:8;s:9:\"separator\";i:9;s:9:\"forecolor\";i:10;s:9:\"backcolor\";i:11;s:8:\"emotions\";i:12;s:9:\"separator\";i:13;s:3:\"sup\";i:14;s:3:\"sub\";i:15;s:5:\"media\";i:16;s:9:\"separator\";i:17;s:4:\"undo\";i:18;s:4:\"redo\";i:19;s:7:\"attribs\";i:20;s:7:\"wp_help\";}", "no"); insert into wp_options (option_id, blog_id, option_name, option_value, autoload) values (202, 0, "tadv_btns3", "a:0:{}", "no"); insert into wp_options (option_id, blog_id, option_name, option_value, autoload) values (203, 0, "tadv_btns4", "a:0:{}", "no"); insert into wp_options (option_id, blog_id, option_name, option_value, autoload) values (204, 0, "tadv_allbtns", "a:64:{i:0;s:6:\"wp_adv\";i:1;s:4:\"bold\";i:2;s:6:\"italic\";i:3;s:13:\"strikethrough\";i:4;s:9:\"underline\";i:5;s:7:\"bullist\";i:6;s:7:\"numlist\";i:7;s:7:\"outdent\";i:8;s:6:\"indent\";i:9;s:11:\"justifyleft\";i:10;s:13:\"justifycenter\";i:11;s:12:\"justifyright\";i:12;s:11:\"justifyfull\";i:13;s:3:\"cut\";i:14;s:4:\"copy\";i:15;s:5:\"paste\";i:16;s:4:\"link\";i:17;s:6:\"unlink\";i:18;s:5:\"image\";i:19;s:7:\"wp_more\";i:20;s:7:\"wp_page\";i:21;s:6:\"search\";i:22;s:7:\"replace\";i:23;s:10:\"fontselect\";i:24;s:14:\"fontsizeselect\";i:25;s:7:\"wp_help\";i:26;s:10:\"fullscreen\";i:27;s:11:\"styleselect\";i:28;s:12:\"formatselect\";i:29;s:9:\"forecolor\";i:30;s:9:\"backcolor\";i:31;s:9:\"pastetext\";i:32;s:9:\"pasteword\";i:33;s:12:\"removeformat\";i:34;s:7:\"cleanup\";i:35;s:12:\"spellchecker\";i:36;s:7:\"charmap\";i:37;s:5:\"print\";i:38;s:4:\"undo\";i:39;s:4:\"redo\";i:40;s:13:\"tablecontrols\";i:41;s:4:\"cite\";i:42;s:3:\"ins\";i:43;s:3:\"del\";i:44;s:4:\"abbr\";i:45;s:7:\"acronym\";i:46;s:7:\"attribs\";i:47;s:5:\"layer\";i:48;s:5:\"advhr\";i:49;s:4:\"code\";i:50;s:11:\"visualchars\";i:51;s:11:\"nonbreaking\";i:52;s:3:\"sub\";i:53;s:3:\"sup\";i:54;s:9:\"visualaid\";i:55;s:10:\"insertdate\";i:56;s:10:\"inserttime\";i:57;s:6:\"anchor\";i:58;s:10:\"styleprops\";i:59;s:8:\"emotions\";i:60;s:5:\"media\";i:61;s:10:\"blockquote\";i:62;s:9:\"separator\";i:63;s:1:\"|\";}", "no");
один способ сделать это:
взорваться ");
он вернет массив утверждений
затем concat ")" в конце каждого оператора в массиве
Учитывая строку, содержащую несколько операторов SQL, разделенных запятой, следующая функция анализирует каждый отдельный оператор и возвращает их все в массиве. Он использует одно (нетривиальное) регулярное выражение и один вызов preg_match_all()
и правильно обрабатывает одиночные и многострочные комментарии, а также строки с одним и двумя кавычками (каждый из которых может содержать недопустимые полуколоны, игнорируются):
function split_sql($sql_text) { // Return array of ; terminated SQL statements in $sql_text. $re_split_sql = '%(?#!php/x re_split_sql Rev:20170816_0600) # Match an SQL record ending with ";" \s* # Discard leading whitespace. ( # $1: Trimmed non-empty SQL record. (?: # Group for content alternatives. \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' # Either a single quoted string, | "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" # or a double quoted string, | /\*[^*]*\*+(?:[^*/][^*]*\*+)*/ # or a multi-line comment, | \#.* # or a # single line comment, | --.* # or a -- single line comment, | [^"\';#] # or one non-["\';#-] )+ # One or more content alternatives (?:;|$) # Record end is a ; or string end. ) # End $1: Trimmed SQL record. %x'; // End $re_split_sql. if (preg_match_all($re_split_sql, $sql_text, $matches)) { return $matches[1]; } return array(); }
Изменить 2017-08-15: Исправлена ошибка в многострочной части комментария регулярного выражения, отмеченной @jxmallett. Edit 2017-08-16: Tidied regex (добавлено regex shebang и удалена ненужная группа $2
).
Мое предложение было бы заменить ваш разделитель чем-то уникальным. Например, точка с запятой не будет уникальной (как вы описали), поэтому вы не можете разделить на нее. Новые строки (как было указано ранее) могут быть хорошим и простым вариантом.
Разделяются ли эти строки символом «новой строки»? Если да, просто взорвите их:
$my_array = explode("\n",$content);
как насчет чего-то подобного
$fh = fopen('/path/to/your/file.sql', 'r') or die($php_errormsg); while (!feof($fh)) { $line = fgets($fh, 4096); if (preg_match($pattern, $line)) { $sql_queries[ ] = $line; } } fclose($fh);
Где $ pattern может быть инициализирован в формате запроса вставки sql. Использование новой строки не будет хорошим вариантом, так как большие вставки sql растягиваются для более чем одной строки