@honeori_aitata

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PHP 正規表現について

解決したいこと

現在PHPでの正規表現で文字列置換を実装中です。
その中で否定形のものがうまく実装できずに困っております。
識者の方、ご教授いただけると幸いです。

発生している問題

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX https://xxx.yyy.zzz/abc/def XXXXX
XXXXXXXX https://xxx.yyy.zzz/abc/def
XXXXXXXX(https://xxx.yyy.zzz/abc/def)XXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

上記の様な文字列があるとしまして
URL部分が「()」に含まれていない2行目または3行目のようなURL部分を
4行目の様に「()」付きに置換したく思っております。

自分で試したこと

下記サイトなどで挙動を確認しております。
PHPのコードというよりも、正規表現の検索、置換後文字列の記述方式を知りたく思っております。

否定的先読みなど試しておりますが、解決できずにおります。
お力お貸しくださいませ。

0 likes

3Answer

URLには()も含まれ得ます。
したがって4行目は
https://xxx.yyy.zzz/abc/def)XXXXX
というURLであるとも解釈できちゃいます。
それはどうするつもりですか?

0Like

Comments

  1. @honeori_aitata

    Questioner

    コメントありがとうございます!
    なるほどなるほど。すみません、説明が不足しておりました。
    今回のURLはある程度制限が入っており、ご指摘の「()」が含まれることはございませんので
    ()の内部がURLと判断できる前提で大丈夫です。

こんなかんじですか?

preg_replace('|^(.*)([^(])(https?://[^\s)]+)([^)])(.*)$|im', '\1\2(\3)\4\5', $str);

4行目のように前後の空白を取りたいのであれば、3行目は末尾に空白がないのでパターンを二つに分けてます。

preg_replace(
    array('|^(.*)([^(])(https?://[^\s)]+)$|im','|^(.*)([^(])(https?://[^\s)]+)([^)])(.*)$|im'),
    array('\1(\3)','\1(\3)\5'), $str);

もっと良い方法がありそうな気はしますが。

0Like

Comments

  1. @honeori_aitata

    Questioner

    お返事大変遅くなしました!
    ご連絡いただきました内容で確認できております。
    大変助かりました。
/(?<!\()(https?:\/\/[a-zA-Z0-9.=~?#%\/]*)\s/gm

これでグループ1がURLになるはずです。
httpの直前に(があればマッチしません。
また、URLの直後が空白(改行でもよし)でなければマッチしません。
URLの:以降は英数字と.=~?#%/の組み合わせのみURLの一部と認識します。この部分は好きなようにすれば良いと思います。

0Like

Comments

  1. @honeori_aitata

    Questioner

    お返事大変遅くなしました!
    ご連絡いただきました内容で確認できております。
    大変助かりました。

Your answer might help someone💌