preg_replace在1行上有多个实例?

时间:2010-08-27 21:47:29

标签: php regex preg-replace poker

我在扑克软件中有这样的文字(我已经突出了我需要更换的部分)。

  

--- FLOP --- [Jh 9h Ah]
  driverseati检查
  达林顿还有15秒的时间来行动   达林顿下注100   InvisibleEnigma调用100
  driverseati折叠
  --- TURN --- [Jh 9h Ah] [3c]
  达林顿下注200
  InvisibleEnigma调用200
  --- RIVER --- [Jh 9h Ah 3c] [Td]

     

Jh =心中的杰克   9h = 9个心脏   啊=心中的王牌   3c = 3个俱乐部

我想用 IMAGES 替换方括号内的卡片。

所以这一行:--- TURN --- [Jh 9h Ah] [3c]
需要成为:--- TURN --- jh.gif 9h.gif ah.gif 3c.gif

我无法弄清楚preg_replace :(我可以想出它只是一个卡在括号内(如[3c]),但我坚持在1行和一些括号上替换多个实例有3张牌和一些括号有2张或1张牌。

这就是我对单张卡的看法:

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

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:1)

如果你正在寻找方括号(如你所知),这很难做到。如果您不尝试匹配它们并只是查找卡名称,无论它们出现在哪里,那么它很简单:

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

\b标记检查字边界。他们确保卡名称必须是不同的字词,因此Ah中的Ahead将不匹配,例如。

处理方括号相当复杂。理想情况下,您可以使用lookahead and lookbehind assertions来检查它们,但是对于后视断言有一个不幸的限制,这使得它们不适合这项工作:

  

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标志以使搜索不区分大小写

答案 1 :(得分:0)

$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

<小时/> 看起来John(差点!)在我砍掉的时候打败了我,虽然我的代码在这里更具体一点 - 它不会在括号内的任何字符串上运行替换,例如[as the world turns],它必须是一套卡片。我也将它限制在括号中的5张卡片,虽然你可以通过简单地调整匹配中的{0,4}来改变它。

答案 2 :(得分:0)

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);