preg_replace несколько экземпляров на 1 строке? - PullRequest
3 голосов
/ 28 августа 2010

У меня есть такой текст из покерного программного обеспечения (я выделил части, которые мне нужно заменить).

--- FLOP --- [Jh 9h Ah]
проверки дриверсати
Даррингтону осталось 15 секунд, чтобы действовать
ставки Даррингтона 100
InvisibleEnigma вызывает 100
сгибов Дриверсати
--- TURN --- [Jh 9h Ah][3c]
Даррингтон ставок 200
InvisibleEnigma вызывает 200
--- РЕКА --- [Jh 9h Ah 3c] [Td]

Jh= Валет сердец
9h = 9 сердец
ах = туз червей
3c = 3 треф

Я хочу заменить карточки внутри квадратных скобок на ИЗОБРАЖЕНИЯ .

Итак, эта строка: --- TURN --- [Jh 9h Ah] [3c]
Должен стать: --- TURN --- jh.gif 9h.gif ah.gif 3c.gif

Я не могу понять preg_replace :( Я могу отчасти понять это только для одной карточки в скобках (например, [3c]), но я застрялпри замене нескольких экземпляров в одной строке и в некоторых скобках по 3 карты и в некоторых скобках по 2 или 1 карточке.

Это то, что у меня есть для одной карточки:

\[([AKQJakqj1-9]0?[DHSCdhsc])\]

Любая помощьбудет оценена.

Ответы [ 3 ]

1 голос
/ 28 августа 2010

Это трудно сделать, если вы ищете квадратные скобки (как вы выяснили).Если вы не пытаетесь сопоставить их и просто ищете названия карт, где бы они ни встречались, тогда это просто:

\b([AKQJakqj1-9]0?[DHSCdhsc])\b

Маркеры \b проверяют границы слов.Они гарантируют, что имя карты должно быть отдельным словом, поэтому, например, Ah в Ahead не будет совпадать.

Обработка квадратных скобок довольно сложная.В идеале вы могли бы использовать утверждения типа lookahead и lookbehind , чтобы проверить их, но есть неблагоприятное ограничение для утверждений lookbehind, которое делает их непригодными для работы:

Содержимое утверждения позадиограничены таким образом, что все строки, с которыми оно совпадает, должны иметь фиксированную длину.

Поэтому вместо этого я пришел к решению двойной замены, использующему флаг /e, чтобы вложить один вызов preg_replace внутридругой.

preg_replace(
    '/\[(.*?)]/e',
    "preg_replace('/(\b[AKQJT1-9]0?[DHSC]\b)/i', '\\\$1.jpg', '$1')",
    $hh
);

Внешнее регулярное выражение ищет квадратные скобки и фиксирует внутренности.Внутреннее регулярное выражение ищет имена карт внутри этого $1 и превращает их в изображения.

Кстати, я добавил T к вашему шаблону, поскольку 10 ♦ обычно записывается как Td в истории руки я добавил флаг i, чтобы сделать поиск нечувствительным к регистру.

0 голосов
/ 28 августа 2010
function imageize($matches)
{
    $from = array('s','c','d','h','[',']');
    $to = array('s.gif','c.gif','d.gif','h.gif','','');
    return $matches[1] . str_replace($from, $to, strtolower($matches[2])) . $matches[3];
}

$str = preg_replace_callback('#([^\[\]]*?)((?: *\[[akqjtcsdh\d ]+\])+)([^\[\]]*?)#i', 'imageize', $str);
0 голосов
/ 28 августа 2010
$string = "--- RIVER --- [Jh 9h Ah 3c] [Td]";

$CARD = "[akqjt1-9][dhsc]";
echo preg_replace(
  "/\[($CARD(?:\s+$CARD){0,4})\]/ie",
  "preg_replace('/\b$CARD\b/i', '\\\$0.gif', '\$1')",
  $string);

Этот код выводит:

--- RIVER --- Jh.gif 9h.gif Ah.gif 3c.gif Td.gif

Похоже, Джон (узко!) Обошел меня, когда я взломал, хотя мой код здесь немного более конкретен - он не будет выполнять замену любой строки внутри скобок, как [as the world turns], это должен быть наборкарточек.Я также ограничил это до 5 карт в скобках, хотя вы можете изменить это, просто изменив значение {0,4} в матче.

...