Регулярное выражение для замены относительной ссылки с корневой относительной ссылкой

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

Замещенные ссылки:

 <tag ... href="path/to_file.ext" ... > ---> <tag ... href="/basepath/path/to_file.ext" ... > <tag ... href="path/to_file.ext" ... /> ---> <tag ... href="/basepath/path/to_file.ext" ... /> 

Нетронутые ссылки:

 <tag ... href="/any/path" ... > <tag ... href="/any/path" ... /> <tag ... href="protocol://domain.com/any/path" ... > <tag ... href="protocol://domain.com/any/path" ... /> 

Если вы просто хотите изменить базовый URI, вы можете попробовать элемент BASE :

 <base href="/basepath/"> 

Но обратите внимание, что изменение базового URI влияет на все относительные URI, а не только на относительные пути URI.

В противном случае, если вы действительно хотите использовать регулярное выражение, считайте, что относительный путь, как вы хотите, должен иметь тип path-noscheme (см. RFC 3986 ):

 path-noscheme = segment-nz-nc *( "/" segment ) segment = *pchar segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) ; non-zero-length segment without any colon ":" pchar = unreserved / pct-encoded / sub-delims / ":" / "@" pct-encoded = "%" HEXDIG HEXDIG unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" 

Итак, начало URI должно совпадать:

 ^([a-zA-Z0-9-._~!$&'()*+,;=@]|%[0-9a-fA-F]{2})+($|/) 

Но, пожалуйста, используйте подходящий HTML-парсер для анализа HTML-кода из сборки DOM. Затем вы можете запросить DOM, чтобы получить атрибуты href и проверить значение с помощью обычного выражения выше.

Я придумал это:

 preg_replace('#href=["\']([^/][^\':"]*)["\']#', $root_path.'$1', $html); 

Это может быть слишком упрощенным. Очевидный недостаток, который я вижу, заключается в том, что он также будет соответствовать href="something" когда он находится вне тега, но, надеюсь, он может вас начать.