Форум программистов, компьютерный форум, киберфорум
Наши страницы
PHP: RegExp
Войти
Регистрация
Восстановить пароль
 
SergTN
0 / 0 / 1
Регистрация: 18.09.2017
Сообщений: 77
#1

Разбиение строки по символу с "отрицанием" - PHP

12.12.2017, 20:47. Просмотров 307. Ответов 9
Метки нет (Все метки)

Пишу регулярку для разбиения строки по символу "запятая", но ту которая не помещена в апострофы с любым количеством пробелов. Т.е разбиение по запятой, а та запятая что в апострофах, не рассматривалась бы как символ разбиения, а как собственно символ и помещалась бы в массив

написал
PHP
1
preg_split('/(?!\'),(?!\')/'.'u', $string)
для строки вида
PHP
1
$string="f, g , h, ',', j, k";
работает корректно
получаю массив
PHP
1
2
3
4
5
6
7
8
Array(
[0] = f
[1] = g
[2] = h
[3] = ','
[4] = j
[5] = k
);
Но если апостроф лежит вплотную к предыдущей запятой, (как после буквы h)
PHP
1
$string="f, g , h,',', j, k";
то получаю некорректное разбиениы
PHP
1
2
3
4
5
6
7
Array(
[0] = f
[1] = g
[2] = h,','
[3] = j
[4] = k
);
то-же самое, если между апострофами и запятой есть пробелы, f, g , h, ' , ', j, k то получаю тоже некорректное разбиение
Array(
[0] = f
[1] = g
[2] = h
[3] = '
[4] = '
[5] = j
[6] = k
);

Что нужно добавить в выражение? Как-то тяжело мне дается регулярка)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.12.2017, 20:47
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Разбиение строки по символу с "отрицанием" (PHP):

Получить последний символ "," или "-" стоящий в конце строки перед цифрами и буквами
Здравствуйте. Имеется примерно такой текст "XX1,XX3-XX11" и нужно получить...

Требуется вытащить цифры и две буква "АА" из строки
Здравствуйте, вообще не силен в регулярных выражениях, обязательно возьмусь и...

Вырезать регуляркой символы в конце строки, если она не заканчивается на "quo;"
Всем привет! Есть такой код, вырезающий из конца строки "ненужные" символы:...

Разрешить "+" только в начале строки
как сделать что бы символ либо был либо не был но только вначале строки Пробую...

Доступ к родительским директориям и файлам echo file_get_contents("./dir1/dir2/".$_REQUEST["password_md5"].".txt");
Доброго времени суток! Помогите пожалуйста пролить свет на вопрос. Есть...

Пропадает знак "+" при передаче строки методом ajax $_POST
В скрипте имеется строка, например "5 + 5 = 10", ее передаю с помощью ajax post...

9
Emilien
496 / 400 / 233
Регистрация: 07.11.2015
Сообщений: 645
13.12.2017, 00:54 #2
Лучший ответ Сообщение было отмечено SergTN как решение

Решение

Исходные данные в формате CSV? Если да, то есть штатные средства под этот формат http://php.net/manual/ru/function.str-getcsv
PHP
1
$a = str_getcsv($string, ',', "'");
Если хочется разбирать регуляркой:
PHP
1
2
3
$string="f, g , h, '10,000', j, k";
$a = preg_split("/\G(?:[^,']+|'[^']*')*+\K,/", $string);
print_r($a);
1
SergTN
0 / 0 / 1
Регистрация: 18.09.2017
Сообщений: 77
13.12.2017, 20:35  [ТС] #3
Цитата Сообщение от Emilien Посмотреть сообщение
preg_split("/\G(?:[^,']+|'[^']*')*+\K,/", $string)
Вот спасибо ! Вы просто волшебник! Работает как часы)
По отдельным классам и символам выражения вроде понимаю, а как это все вместе работает не доходит)
А правильно-ли модификатор u (для UTF-8) так добавить:
PHP
1
preg_split("/\G(?:[^,']+|'[^']*')*+\K,/".'u'
?
0
Emilien
496 / 400 / 233
Регистрация: 07.11.2015
Сообщений: 645
13.12.2017, 20:53 #4
Да, для работы с UTF-8 стоит добавить модификатор u.
Шаблон захватывает всё до ближайшей запятой, а последовательность \K используется для сброса начала совпадения http://php.net/manual/ru/regexp.reference.escape.php
0
SergTN
0 / 0 / 1
Регистрация: 18.09.2017
Сообщений: 77
13.12.2017, 22:06  [ТС] #5
Пробую теперь выбрать все что внутри этих крайних апострофов
/\b'(.+)'\b/
-работат только на внутренних апострофах, а не на внешних. Пробовал на http://easyregexp.ru/constructor
Ничего не понимаю
0
Emilien
496 / 400 / 233
Регистрация: 07.11.2015
Сообщений: 645
13.12.2017, 22:55 #6
Цитата Сообщение от SergTN Посмотреть сообщение
Пробую теперь выбрать все что внутри этих крайних апострофов
/\b'(.+)'\b/
-работат только на внутренних апострофах, а не на внешних. Пробовал на http://easyregexp.ru/constructor
Ничего не понимаю
\b - граница слова. Ей соответствует позиция между двумя символами текста, когда один из них является символом слова, а другой – нет.
К символам слова относят состав метасимвола \w т.е. буквы, цифры и подчёркивание.
Кавычка не является символом слова.
Фрагмент \b' может совпасть только если перед кавычкой окажется буква, цифра или подчёркивание.
Аналогично '\b для совпадения после кавычки нужна буква, цифра или подчёркивание.
.+ по умолчанию квантификаторы жадные и эта конструкция захватит максимум текста аж до самой последней кавычки.
1
SergTN
0 / 0 / 1
Регистрация: 18.09.2017
Сообщений: 77
14.12.2017, 00:19  [ТС] #7
наверное здесь проще вырезать обычными строковыми функциями обойтись -т.к. по идее для регулярки это несложная замена?

Добавлено через 4 минуты
Цитата Сообщение от Emilien Посмотреть сообщение
Фрагмент \b' может совпасть только если перед кавычкой окажется буква, цифра или подчёркивание.
Аналогично '\b для совпадения после кавычки нужна буква, цифра или подчёркивание.
а для первого или последнего слова в строке эта граница сработает? Я сейчас не про символ ' а про общий случай
0
Emilien
496 / 400 / 233
Регистрация: 07.11.2015
Сообщений: 645
14.12.2017, 04:06 #8
Лучший ответ Сообщение было отмечено SergTN как решение

Решение

Цитата Сообщение от SergTN Посмотреть сообщение
а для первого или последнего слова в строке эта граница сработает? Я сейчас не про символ ' а про общий случай
Граница слова совпадает с позицией перед первым символом текста, если первый символ является символом слова.
И с позицией после последнего символа текста, если последний символ является символом слова.


Цитата Сообщение от SergTN Посмотреть сообщение
наверное здесь проще вырезать обычными строковыми функциями обойтись -т.к. по идее для регулярки это несложная замена?
Проще сразу воспользоваться str_getcsv, fgetcsv.


Цитата Сообщение от SergTN Посмотреть сообщение
Пробую теперь выбрать все что внутри этих крайних апострофов
/\b'(.+)'\b/
С помощью preg_match_all и сброса нумерации в ветвлении (?|...) можно сразу получить значение без этих крайних апострофов.
PHP
1
2
3
$string="f, g , h, '10,000', j, k";
preg_match_all("/(?|([^,']+)|'([^']*)')(?:\s*,\s*|$)/u", $string, $a);
print_r($a[1]);
1
SergTN
0 / 0 / 1
Регистрация: 18.09.2017
Сообщений: 77
14.12.2017, 20:44  [ТС] #9
Огромное спасибо!
Правда, еще более стал паттерн непонятнее) Можно поподробнее прокоментировать этот кусочек:
Цитата Сообщение от Emilien Посмотреть сообщение
..)(?:\s*,\s*|$)/u"
0
Emilien
496 / 400 / 233
Регистрация: 07.11.2015
Сообщений: 645
16.12.2017, 18:04 #10
Там или захват пробельных символов вокруг запятой или конец строки.
0
16.12.2017, 18:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.12.2017, 18:04
Привет! Вот еще темы с решениями:

Какую книгу выбрать из "PHP 5 Второе издание (авторы Котеров и Костарев)" и "Джентельменский набор WEB-мастера".
Приветствую всех. Есть две книги : PHP 5 2ое издание , Авторы Котеров и...

Как запретьть ввод в адресной строке знаков "?" и "&" ?
Подскажите пожалуйста как можно сделать так чтоб если пользователь в адресной...

getimagesize() vs $_FILES["img"]["type"] - узнать тип изображения
Как лучше проверять тип файла? Необходимо запретить закачку любых файлов, кроме...

Для чего используются "virtual_path" и "ifelse:system_enable_fancy_urls"?
Приветик, народ! Помогите, плиз, разобраться со строчкой. Есть движок сайта,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru