文本识别为超链接

通过正则表达式将文本中的链接转换为超链接

  1. // ==UserScript==
  2. // @name Convert Text to Hyperlink
  3. // @name:zh-CN 文本识别为超链接
  4. // @namespace https://github.com/KPI0/tampermonkey
  5. // @version 1.5
  6. // @description Convert URLs in text nodes to hyperlinks using regular expressions
  7. // @description:zh-cn 通过正则表达式将文本中的链接转换为超链接
  8. // @author KPI0
  9. // @match *://*/*
  10. // @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzI4MTE3NTk1Mjc5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE2MjAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTU3My40NCA2NDBhMTg3LjY4IDE4Ny42OCAwIDAgMS0xMzIuOC01NS4zNkw0MTYgNTYwbDQ1LjI4LTQ1LjI4IDI0LjY0IDI0LjY0YTEyNC4zMiAxMjQuMzIgMCAwIDAgMTcwLjA4IDUuNzZsMS40NC0xLjI4YTQ5LjQ0IDQ5LjQ0IDAgMCAwIDQtMy44NGwxMDEuMjgtMTAxLjI4YTEyNC4xNiAxMjQuMTYgMCAwIDAgMC0xNzZsLTEuOTItMS45MmExMjQuMTYgMTI0LjE2IDAgMCAwLTE3NiAwbC01MS42OCA1MS42OGE0OS40NCA0OS40NCAwIDAgMC0zLjg0IDRsLTIwIDI0Ljk2LTQ5LjkyLTQwTDQ4MCAyNzYuMzJhMTA4LjE2IDEwOC4xNiAwIDAgMSA4LjY0LTkuMjhsNTEuNjgtNTEuNjhhMTg4LjE2IDE4OC4xNiAwIDAgMSAyNjYuNzIgMGwxLjkyIDEuOTJhMTg4LjE2IDE4OC4xNiAwIDAgMSAwIDI2Ni43MmwtMTAxLjI4IDEwMS4yOGExMTIgMTEyIDAgMCAxLTguNDggNy44NCAxOTAuMjQgMTkwLjI0IDAgMCAxLTEyNS4yOCA0OHoiIGZpbGw9IiMzMzMzMzMiIHAtaWQ9IjE2MjEiPjwvcGF0aD48cGF0aCBkPSJNMzUwLjcyIDg2NGExODcuMzYgMTg3LjM2IDAgMCAxLTEzMy4yOC01NS4zNmwtMS45Mi0xLjkyYTE4OC4xNiAxODguMTYgMCAwIDEgMC0yNjYuNzJsMTAxLjI4LTEwMS4yOGExMTIgMTEyIDAgMCAxIDguNDgtNy44NCAxODguMzIgMTg4LjMyIDAgMCAxIDI1OC4wOCA3Ljg0TDYwOCA0NjRsLTQ1LjI4IDQ1LjI4LTI0LjY0LTI0LjY0QTEyNC4zMiAxMjQuMzIgMCAwIDAgMzY4IDQ3OC44OGwtMS40NCAxLjI4YTQ5LjQ0IDQ5LjQ0IDAgMCAwLTQgMy44NGwtMTAxLjI4IDEwMS4yOGExMjQuMTYgMTI0LjE2IDAgMCAwIDAgMTc2bDEuOTIgMS45MmExMjQuMTYgMTI0LjE2IDAgMCAwIDE3NiAwbDUxLjY4LTUxLjY4YTQ5LjQ0IDQ5LjQ0IDAgMCAwIDMuODQtNGwyMC0yNC45NiA1MC4wOCA0MC0yMC44IDI1LjEyYTEwOC4xNiAxMDguMTYgMCAwIDEtOC42NCA5LjI4bC01MS42OCA1MS42OEExODcuMzYgMTg3LjM2IDAgMCAxIDM1MC43MiA4NjR6IiBmaWxsPSIjMzMzMzMzIiBwLWlkPSIxNjIyIj48L3BhdGg+PC9zdmc+
  11. // @grant none
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17.  
  18. // Regular expression to match URLs starting with http or https
  19. const urlRegex = /(http:\/\/[^\s]+|https:\/\/[^\s]+)/g;
  20.  
  21. function convertTextLinksToHyperlinks(node) {
  22. if (node.nodeType === Node.TEXT_NODE) {
  23. const text = node.nodeValue;
  24. const matches = text.match(urlRegex);
  25.  
  26. if (matches) {
  27. const span = document.createElement('span');
  28. let lastIndex = 0;
  29.  
  30. matches.forEach((match) => {
  31. const matchIndex = text.indexOf(match, lastIndex);
  32.  
  33. // Append normal text
  34. if (matchIndex > lastIndex) {
  35. span.appendChild(document.createTextNode(text.substring(lastIndex, matchIndex)));
  36. }
  37.  
  38. // Create hyperlink element
  39. const link = document.createElement('a');
  40. link.href = match;
  41. link.target = '_blank'; // Open in a new tab
  42. link.textContent = match;
  43. span.appendChild(link);
  44.  
  45. lastIndex = matchIndex + match.length;
  46. });
  47.  
  48. // Append remaining normal text
  49. if (lastIndex < text.length) {
  50. span.appendChild(document.createTextNode(text.substring(lastIndex)));
  51. }
  52.  
  53. node.parentNode.replaceChild(span, node);
  54. }
  55. } else if (node.nodeType === Node.ELEMENT_NODE) {
  56. // Skip certain tags that should not contain links or be processed
  57. const skipTags = ['A', 'SCRIPT', 'STYLE', 'IMG', 'VIDEO', 'AUDIO', 'PICTURE', 'IFRAME', 'BUTTON', 'CANVAS', 'NAV', 'HEADER', 'FOOTER'];
  58. if (!skipTags.includes(node.tagName)) {
  59. // Recursively process child nodes
  60. for (let child of Array.from(node.childNodes)) {
  61. convertTextLinksToHyperlinks(child);
  62. }
  63. }
  64. }
  65. }
  66.  
  67. // Execute after the page has fully loaded
  68. window.addEventListener('load', function () {
  69. const mainContentSelectors = ['#main', '.content', '.article', '#content', '.post', '.entry']; // Common main content containers
  70. mainContentSelectors.forEach(selector => {
  71. const container = document.querySelector(selector);
  72. if (container) {
  73. convertTextLinksToHyperlinks(container);
  74. }
  75. });
  76. });
  77.  
  78. })();