The easiest way to accomplish this task is by using the following regex pattern:
/<a href="([^>]*)">(.+)<\/a>/
.
Test example:
console.clear()
const parseVueLinks = ($value) => {
const re = /<a href="([^>]*)">(.+)<\/a>/g;
const matches = re.exec($value);
return `<router-link :to="{ path: '${matches[1]}'}">${matches[2]}</router-link>`
}
console.log(parseVueLinks('<a href="/about-us">Text</a>'))
console.log(parseVueLinks('<a href="http://google.com">Goooooogle</a>'))
I am not familiar with PHP, but I believe the equivalent PHP code might be (tested at https://www.functions-online.com/preg_match.html):
function parseVueLinks($value)
{
$pattern = "/<a href="([^>]*)">(.+)<\/a>/";
$matches = [];
preg_match($pattern, $replace, $matches);
return "<router-link :to=\"{ path: '" + $matches[1] + "'}\">" + $matches[2] + "</router-link>";
}
I am curious about the inclusion of http|https|mailto|tel
in your regex. Are you looking to validate the link?
If that is the case, utilizing preg_match()
allows for a secondary regex step on $matches[1]
before output. It might be more straightforward to validate as a separate step rather than using one comprehensive regex.
Edit the comment below
The issue does not lie in the regex itself. The problem arises from Vue's inability to interpret content retrieved from the server
This may not be applicable if you are employing server-side rendering. However, this is how I implement links from content.
MyComponent.ts
<template>
<div class="row">
...
<router-link :to="'/' + measure.link" class="measure">
<i class="measure-icon fa fa-lg" :class="measure.icon" aria-hidden="true">
<span class="title">{{measure.title}}</span>
</i>
</router-link>
In this scenario, measure
represents an object fetched from the server. If you retrieve the entire <router-link>
, it may work well with a Dynamic Component, but it appears to be excessive since you already "know" the element will be a <router-link
.
If the server responds to clicks with a 404, you can utilize hash-mode routing (default) by adding # before the link, e.g #/about-us
.
Alternatively, enable history mode in the Vue router.
const router = new Router({
routes,
mode: 'history'
})
For this to work, the server must redirect to index.html
for a 404 error. Refer to HTML History Mode.
Additionally, you need to handle 404 errors in Vue with a catch-all route,
const routes = [
...
{ path: '*', component: NotFoundComponent },
]