Я хочу заменить все запятые, которые существуют в скобках или квадратных скобках, используя preg_replace.
Я могу заменить все запятые внутри скобок, используя следующее:
$clean_ingredients = preg_replace('/(\([^)]*),([^)]*\))/', '$1! $2', $ingredients );
Это приводит к замене запятых внутри скобок, но я не могу понять, как также проверять запятые внутри квадратных скобок.
Чего я хотел бы добиться, так это:
$ingredients = "Skim Milk Powder, Condensed Milk, Coconut Cream, Strawberry Jam [Cane Sugar, Strawberries (40%), Gelling Agent (Fruit Pectin), Acidity Regulator (330)], Hazelnuts, Barley Malt Extract, Emulsifier (Soya Lecithin), Peppermint [Vegetable Oil, Peppermint Oil, Antioxidant (Mixed Tocopherols Concentrate)], Salt, Citric Acid, Flavouring (Vanillin), Vanilla, Colouring (E102, E133, E129, E132, E171, E122, E124, E110, E172, E153).";
$clean_ingredients = preg_replace('????', '$1! $2', $ingredients );
echo $clean_ingredients;
// Output: Skim Milk Powder, Condensed Milk, Coconut Cream, Strawberry Jam [Cane Sugar! Strawberries (40%)! Gelling Agent (Fruit Pectin)! Acidity Regulator (330)], Hazelnuts, Barley Malt Extract, Emulsifier (Soya Lecithin), Peppermint [Vegetable Oil! Peppermint Oil! Antioxidant (Mixed Tocopherols Concentrate)], Salt, Citric Acid, Flavouring (Vanillin), Vanilla, Colouring (E102! E133! E129! E132! E171! E122! E124! E110! E172! E153).
Есть ли какие-нибудь эксперты по регулярным выражениям, которые знают, что может достичь того, что мне нужно?
Если скобки и квадратные скобки сбалансированы, а предложения в скобках и скобках не являются вложенными, вы можете заменить совпадения ,(?=[^[]*]|[^(]*\)) на '!'. Демо






Вы можете использовать
<?php
$ingredients = "aaa (1,2,3) bbb [4,5,6,7]";
$clean_ingredients = preg_replace_callback('/\([^()]*\)|\[[^][]*]/', function($m) {return str_replace(',', '! ', $m[0]);}, $ingredients );
echo $clean_ingredients;
// => aaa (1! 2! 3) bbb [4! 5! 6! 7]
Посмотрите демонстрацию PHP и демонстрацию регулярных выражений.
Регулярное выражение \([^()]*\)|\[[^][]*] соответствует
\([^()]*\) - символ ( + ноль или более символов, кроме ( и ) + символ )| - или\[[^][]*] - символ [ + ноль или более символов, кроме [ и ] + символ ].Функция внутри preg_replace_callback заменяет все запятые на ! + пробел.
В {return str_replace(',', '! ', $m[0]);} уберите пробел в конце ! .
Работает как мечта для моего сценария. Спасибо!
@l'L'l Пробел не мой, он есть в строке замены OP, см. $1! $2. Если это нужно ОП, я не могу просто опустить это в ответе.
@WiktorStribiżew: после каждого слова полученной строки замены, содержащей «!», был дополнительный пробел. в конце; при пропуске пробела в замене регулярного выражения вывод выглядел точно так же, как и желаемый OP. (например, E102! E133! E129! против E102! E133! E129!)
@WiktorStribiżew: я понимаю, в чем проблема; в вашем примере у вас есть (1,2,3...), тогда как у OP есть (1, 2, 3...), и почему лишние пробелы.
В этом случае я бы просто заменил str_replace(',', '! ', $m[0]) на preg_replace('~,\s*~', '! ', $m[0]), чтобы добавить один пробел после !.
$ingredients = "Skim Milk Powder, Condensed Milk, Coconut Cream, Strawberry Jam [Cane Sugar, Strawberries (40%), Gelling Agent (Fruit Pectin), Acidity Regulator (330)], Hazelnuts, Barley Malt Extract, Emulsifier (Soya Lecithin), Peppermint [Vegetable Oil, Peppermint Oil, Antioxidant (Mixed Tocopherols Concentrate)], Salt, Citric Acid, Flavouring (Vanillin), Vanilla, Colouring (E102, E133, E129, E132, E171, E122, E124, E110, E172, E153).";
echo preg_replace_callback('~\[[^]]+|\([^)]+~', fn($m) => strtr($m[0], ',', '!'), $ingredients);
Как насчет того, чтобы извлечь часть в скобках, разделить ее на
,и затем соединить с!?