Php 是否在一行中替换多个实例?

Php 是否在一行中替换多个实例?,php,regex,preg-replace,poker,Php,Regex,Preg Replace,Poker,我从扑克软件中得到了这样的文本(我突出显示了需要更换的部件) ---扑通一声--[Jh 9h Ah] 驱动器ATI检查 达林顿还有15秒行动 达林顿赌100英镑 InvisibleeIgma呼叫100次 driverseati褶皱 ---旋转--[Jh 9h Ah][3c] 达林顿赌200英镑 InvisibleeIgma呼叫200次 ---河流--[Jh 9h Ah 3c][Td] Jh=红心杰克 9h=9颗心脏 Ah=心的王牌 3c=3个俱乐部 我想用图像替换方括号内的卡 所以这句话:---

我从扑克软件中得到了这样的文本(我突出显示了需要更换的部件)

---扑通一声--[Jh 9h Ah]
驱动器ATI检查
达林顿还有15秒行动
达林顿赌100英镑
InvisibleeIgma呼叫100次
driverseati褶皱
---旋转--[Jh 9h Ah][3c]
达林顿赌200英镑
InvisibleeIgma呼叫200次
---河流--[Jh 9h Ah 3c][Td]

Jh=红心杰克
9h=9颗心脏
Ah=心的王牌
3c=3个俱乐部

我想用图像替换方括号内的卡

所以这句话:---转身--
[Jh 9h Ah][3c]
需要变成:----转身--jh.gif 9h.gif ah.gif 3c.gif

我不知道preg_replace是什么:(我只知道括号内的一张卡(比如[3c]),但我一直在替换一行上的多个实例,有些括号有3张卡,有些括号有2张或1张卡

这是我为一张卡准备的:

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

任何帮助都将不胜感激。

如果您正在查找方括号(正如您所发现的那样),则很难做到这一点。如果您不尝试匹配它们,而只是查找卡片名称,无论它们出现在何处,则很容易:

\b([AKQJakqj1-9]0?[DHSCdhsc])\b
\b
标记检查单词边界。它们确保卡名必须是一个不同的单词,因此前面的
中的
Ah
将不匹配

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

lookbehind断言的内容受到限制,因此它匹配的所有字符串必须具有固定长度

因此,我提出了一个双替换解决方案,使用
/e
标志将一个
preg\u replace
调用嵌套在另一个调用中

preg_replace(
    '/\[(.*?)]/e',
    "preg_replace('/(\b[AKQJT1-9]0?[DHSC]\b)/i', '\\\$1.jpg', '$1')",
    $hh
);
外部正则表达式查找方括号并捕获内部。内部正则表达式查找
$1
中的卡名并将其转换为图像

顺便说一句,我从10年前就在你的模式中添加了
T
♦ 在手动历史记录中通常写为
Td
,我添加了
I
标志以使搜索不区分大小写

$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(勉强!)在我黑客攻击时击败了我,虽然我这里的代码更具体一些-它不会在括号内的任何字符串上运行替换,比如
[随着世界的变化]
,它必须是一组卡。我还将其限制为括号内的5张卡,尽管您可以通过简单地调整
{0,4}来更改它
在匹配中。

这确实有效,但像“as”这样的常用词也将被替换。因此我需要告诉regex只在括号内查看。你必须匹配小写版本吗?这些版本会出现在自动手写历史记录中吗?我还想在常规文本中替换它(就像博客帖子一样,当用户说——嗯,我在玩[ac][Kd Kd]和lost——意思是玩梅花王牌和钻石王)。所以我想替换原始帖子和用户发布信息中粘贴的手记录日志。我很好奇,为什么
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);