We had the same issue a while ago and solved it by using Nvelocity. Might not be the best solution (if there is a nicer one I would also love to see it) but it works.
What I did: in your variant, don't use Field but Template (for a NVelocity template). In the template you can do something like this:
#set ($url = $item.Fields.YourLinkField.ToString())
#if ($url != "")
<a href="$url" target="_blank">YOUR TEXT</a>
#end
The "if" construction is to make sure we don't display an empty link when nothing was set. Replace "YourLinkField" with the name of the link field in your template. If you need to add more logic, you can..
The template is not shared, so you could translate the text if needed.
One step further
If you want to extend this -like I did- and want the editor to change the text more easliy you can create your own NVelocity token and use something like this:
#set ($url = $item.Fields.YourLinkField.ToString())
#if ($url != "")
<a href="$url" target="_blank">$translationTool.GetTranslation("Key")</a>
#end
The $translationTool.GetTranslation("Key")
refers to custom code and might get the value from the Dictionary (or anywhere you want).
To create such a custom variant token, you can check the blog from Michael West who wrote a good article on it: https://michaellwest.blogspot.com/2017/04/custom-rendering-variant-token-tool-for-sxa.html You need to add a processor to the getVelocityTemplateRenderers
pipeline.