Как я могу преобразовать тег [url] в bbcode в тег <a> с атрибутом href и текстом между открывающим и закрывающим тегами?
Вот несколько примеров строк:
[url]https://any.com/any[/url]
[URL = "https://any.com/any?any=333"]text text[/URL]
[url]http://www.any.com/any?any=44#sss[/url]
* Обратите внимание, что подстрока в двойных кавычках в открывающем теге [url] является необязательной и влияет на желаемый результат ...
Я пробовал этот шаблон:
(?:\[url = "(https?://(?:www)?.+?)\]|\[url\](https?://(?:www)?.+\[))
\[url = "(https?://(?:www\.)?.+?)\]|\[url\](https?://(?:www\.)?.+)\[/url\]
\[url = "(https?://(?:www\.)?.+)"\]|\[url\](https?://(?:www\.)?.+)\[/url\]
с чем-то вроде:
$pattern ='##i';
$text = preg_replace($pattern,'',$text);
Мой желаемый результат из приведенных выше тегов URL-адреса bbcode должен быть:
<a href = "https://any.com/any">https://any.com/any</a>
<a href = "https://any.com/any?any=333">text text</a>
<a href = "http://www.any.com/any?any=44#sss">http://www.any.com/any?any=44#sss</a>
Другими словами, если URL-адрес находится в части открывающего тега [url], заключенной в двойные кавычки, используйте это значение в качестве значения href и сохраните innerHTML тега [url] в качестве innerHTML сгенерированного тега <a>.
Если URL-адрес не заключен в двойные кавычки, но находится между открывающим и закрывающим тегами [url], используйте это значение как в качестве значения href, так и в качестве внутреннего HTML-кода <a>.






Вы могли бы использовать
(?i)\[url(?| = "(?P<url>[^"]+)|\](?P<url>[^][]+))
(?i) # case insensitive
\[url # [url
(?| # branch reset
= "(?P<url>[^"]+) # either = "..."
| # or
\](?P<url>[^][]+) # ]...[/url]
)
В любом случае вам понадобится группа "url".
Это не сохраняет innerHTML тега bbcode.
@mickmackusa: это можно сделать, если вы включите атрибут url дважды в группу захвата: regex101.com/r/b0UVWh/2
@Casimir умная игра.
UPDATE: Casimir's commented solution is more direct/clean.
Код: (Демо) (Демонстрация паттернов)
echo preg_replace('~\[url(?|]((https?://[^[]+))|(?: = "(https?://[^"]+)")](.+?))\[/url]~i', '<a href=\"$1\">$2</a>', $bbcode);
Удвоив захват первой альтернативы в шаблоне, вы можете гарантировать, что у вас всегда есть $1 и $2 для применения к строке замены.
Вот немного расширенная вариация узора, который учитывает одинарное цитирование и отсутствие цитирования.
(Начало предыдущего решения)
Используя preg_match_callback(), вы можете определить, был ли указан URL-адрес внутри открывающего тега [url] - и в этом случае вы захотите сохранить текст, расположенный между открывающим и закрывающим тегами.
Если текст между тегами ЯВЛЯЕТСЯ URL-адресом, вы используете его в обоих местах в строке тега <a>.
Недействительные строки не будут преобразованы.
Код: (Демо) (Демонстрация паттернов).
$bbcodes = [
'[URL]www.no.http.example.com[/URL]',
'[url]https://any.com/any[/url]',
'[url = "nourl"]nourl[/url]',
'[URL = "https://any.com/any?any=333"]text text[/URL]',
'[url = "http://www.emptyTEXT.com"][/url]',
'[url]http://www.any.com/any?any=44#sss[/url]',
'[url = "https://conflictinglink"]http://differenturl[/url]'
];
foreach ($bbcodes as $bbcode) {
echo preg_replace_callback('~\[url(?:](https?://[^[]+)|(?: = "(https?://[^"]+)")](.+?))\[/url]~i',
function($m) {
if (isset($m[2])) {
return "<a href=\"{$m[2]}\">{$m[3]}</a>";
}
return "<a href=\"{$m[1]}\">{$m[1]}</a>";
},
$bbcode);
echo "\n---\n";
}
Выход:
[URL]www.no.http.example.com[/URL]
---
<a href = "https://any.com/any">https://any.com/any</a>
---
[url = "nourl"]nourl[/url]
---
<a href = "https://any.com/any?any=333">text text</a>
---
[url = "http://www.emptyTEXT.com"][/url]
---
<a href = "http://www.any.com/any?any=44#sss">http://www.any.com/any?any=44#sss</a>
---
<a href = "https://conflictinglink">http://differenturl</a>
---
Разбивка паттернов:
~ #start of pattern delimiter
\[url #match literally [url
(?: #start non-capturing group #1
] #match literally ]
(https?://[^[]+) #match and store as Capture Group #1 http , an optional s , colon , two forward slashes, then one or more non-opening square brackets (since valid href values cannot have square brackets)
| #or
(?: #start non-capturing group #2
= " #match literally = "
(https?://[^"]+) #match and store as Capture Group #2 (same logic as Capture Group #1)
" #match literally "
) #end non-capturing group #2
] #match literally ]
(.+?) #match (lazily) and store as Capture Group #3 one or more characters (this is the innerHTML component)
) #end non-capturing group #1
\[/url] #match literally [/url]
~ #end of pattern delimiter
Функция обратного вызова оценивает элементы в массиве Спички ($m) и условно генерирует и возвращает желаемый результат. Если есть какие-либо совпадения, вывод будет содержать:
array(
0 => [the fullstring match]
1 => [the url of a bbcode tag that does not have a quoted url]
)
или же
array(
0 => [the fullstring match]
1 => '' // <-- empty string
2 => [the quoted url of the bbcode tag]
3 => [the text between the opening an closing bbcode tags]
)
как я могу сделать это регулярное выражение regex101.com этот код PHP 3v4l.org/kY1eb resut <iframe width = "560" height = "315" src = "youtube.com/embed/Z7Oc8QaM5VU">https://www.youtube.com/…>" frameborder = "0"> </iframe> положить я хочу <iframe width = "560 "height = " 315 "src = " youtube.com/embed/Z7Oc8QaM5VU "> frameborder = " 0 "> </iframe>
Это нетривиальная просьба. Вы, безусловно, должны стремиться достичь желаемого результата с помощью одного рисунка. Это может дать вам некоторую необходимую информацию: stackoverflow.com/a/48968340/2943403 Продолжайте пытаться решить проблему самостоятельно. Подобные проблемы делают вас лучшим разработчиком. Скажите себе, что вы можете это сделать, и продолжайте. Когда вы улучшили свой сниппет, но застряли на каком-то конкретном моменте, вы можете задать новый вопрос. Сообщество здесь очень талантливое.
P.s. если вы хотите сопоставить буквальную точку, например www., вы должны экранировать точку, как эта \.. Модификатор шаблона s (между # и i) заставляет точки «любой символ» также соответствовать символам новой строки - функция, которая, как мне кажется, не требуется для вашего шаблона.
@Hosam вот мое быстрое / грязное / необъяснимое решение: 3v4l.org/aUaYl
Связанный: stackoverflow.com/q/15998847/2943403stackoverflow.com/q/9900385/2943403