Saya mencoba membuat regex yang menemukan alamat email mentah dari teks isi panjang yang belum ditautkan dalam HTML. Contohnya,

  • <a href="mailto:name@example.com">name@example.com</a> harus mengembalikan false
  • name@example.com harus mengembalikan true

Dan saya ingin menggantinya dengan alamat email yang ditautkan dengan benar.

Saya sudah mencoba:

html = html.replaceAll(
/(?:(?!href=['"]mailto:)(?!<a.*?>))([a-zA-Z0-9+._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)(?:(?!<\/a>))/gi, 
"<a href=\'mailto:$1\'>$1</a>"
);

Idenya adalah untuk menemukan alamat email yang tidak memiliki href='mailto: atau tag <a> sebelum email, dan tidak memiliki </a> setelah email. Namun, tampaknya tampilan negatif ?! tidak memberi saya hasil yang diinginkan:

let regex = new RegExp(/(?:(?!href=['"]mailto:)(?!<a.*?>))([a-zA-Z0-9+._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)(?:(?!<\/a>))/, 'gi');
console.log(regex.test("href='mailto:name@example.com"))

Seperti yang dapat Anda lihat dari cuplikan di atas, meskipun menambahkan lookahead negatif, pengujian href='mailto:name@example.com terhadap regex menghasilkan true.

Saya juga mencoba:

(.*)^(?:(?!href=['"]mailto:)(?!<a.*?>))([a-zA-Z0-9+._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)(?:(?!<\/a>))

Itu tidak cocok dengan email dengan awalan href='mailto: tapi sekarang

regex.test("1: name@example.com") // returns false

Alamat email bisa inline jadi saya tidak bisa menggunakan operator ^ di awal.

Adakah ide tentang bagaimana saya bisa mencapai ini? Terima kasih sebelumnya.

1
Parzival 23 April 2021, 05:15

1 menjawab

Jawaban Terbaik

Salah satu pendekatan adalah melakukan penggantian regex dengan fungsi panggilan balik pada pola berikut:

<a href="mailto:\S+">.*?<\/a>|\S+@\S+\.\S+

Ini menggunakan trik bergantian untuk mencoba menemukan tag jangkar terlebih dahulu yang sudah memiliki alamat email di dalamnya. Kegagalan itu, pergantian kembali untuk menemukan alamat email di tempat lain dalam teks.

var input = "Here is a tag with email <a href=\"mailto:name@example.com\">name@example.com</a> and here is just the email name@example.com";
console.log("INPUT: " + input);
var output = input.replace(/<a href="mailto:\S+">.*?<\/a>|\S+@\S+\.\S+/g, function(match, contents, offset, inp)
    {
        if (/<a href="mailto:\S+">.*?<\/a>/.test(match)) {
            return match;
        }
        else {
            return "<a href=\"mailto:" + match + "\">" + match + "<\/a>";
        }
    }
);
console.log("OUTPUT: " + output);

Dalam cuplikan kode di atas, fungsi panggilan balik memeriksa apakah kecocokan menjadi tag jangkar yang sudah memiliki alamat email, dalam hal ini hanya mengembalikan kecocokan yang sama. Untuk semua alamat email lainnya, itu membungkusnya dalam tag jangkar dan kemudian mengembalikan penggantian itu.

1
Tim Biegeleisen 23 April 2021, 02:28