Câu hỏi JavaScript - chuỗi regex backreferences


Bạn có thể backreference như thế này trong JavaScript:

var str = "123 $test 123";
str = str.replace(/(\$)([a-z]+)/gi, "$2");

Điều này sẽ (khá ngớ ngẩn) thay thế "$ test" với "test". Nhưng hãy tưởng tượng tôi muốn chuyển chuỗi kết quả là $ 2 vào một hàm, trả về một giá trị khác. Tôi đã thử làm điều này, nhưng thay vì nhận được chuỗi "thử nghiệm", tôi nhận được "$ 2". Có cách nào để đạt được điều này?

// Instead of getting "$2" passed into somefunc, I want "test"
// (i.e. the result of the regex)
str = str.replace(/(\$)([a-z]+)/gi, somefunc("$2"));

76
2018-03-15 14:44


gốc




Các câu trả lời:


Như thế này:

str.replace(regex, function(match, $1, $2, offset, original) { return someFunc($2); })

105
2018-03-15 14:51



Tuyệt vời, tôi có thể tìm thêm thông tin về điều này ở đâu? - quano
developer.mozilla.org/en/Core_JavaScript_1.5_Reference/… - SLaks
Mát mẻ. Làm rõ: $1 và $2 là các tên tham số do người dùng chọn ở đây (được chọn để bắt chước các ký hiệu backreference); sự thay đổi! - số lượng các tham số này tương ứng với số lượng nhóm chụp trong regex. - mklement0


Vượt qua một hàm làm đối số thứ hai replace:

str = str.replace(/(\$)([a-z]+)/gi, myReplace);

function myReplace(str, group1, group2) {
    return "+" + group2 + "+";
}

Khả năng này đã được khoảng từ Javascript 1.3, theo mozilla.org.


28
2018-03-15 14:52





Chú thích: Câu trả lời trước đã thiếu một số mã. Nó bây giờ là cố định + ví dụ.


Tôi cần một cái gì đó linh hoạt hơn một chút cho một regex thay thế để giải mã unicode trong dữ liệu JSON đến của tôi:

var text = "some string with an encoded 's' in it";

text.replace(/&#(\d+);/g, function() {
  return String.fromCharCode(arguments[1]);
});

// "some string with an encoded 's' in it"

0
2018-02-24 12:58





Sử dụng ESNext, một liên kết giả thay thế nhưng chỉ để hiển thị trường hợp nó hoạt động như thế nào:

let text = 'Visit http://lovecats.com/new-posts/ and https://lovedogs.com/best-dogs NOW !';

text = text.replace(/(https?:\/\/[^ ]+)/g, (match, link) => {
  // remove ending slash if there is one
  link = link.replace(/\/?$/, '');
  
  return `<a href="${link}" target="_blank">${link.substr(link.lastIndexOf('/') +1)}</a>`;
});

document.body.innerHTML = text;


0
2018-06-08 18:54





Nếu bạn sẽ có một số lượng thay đổi của backreferences thì số đối số (và địa điểm) cũng là biến. Các Tài liệu web MDN mô tả cú pháp follwing cho sepcifing một hàm làm đối số thay thế:

function replacer(match[, p1[, p2[, p...]]], offset, string)

Ví dụ: sử dụng các cụm từ thông dụng sau:

var searches = [
    'test([1-3]){1,3}',  // 1 backreference
    '([Ss]ome) ([A-z]+) chars',  // 2 backreferences
    '([Mm][a@]ny) ([Mm][0o]r[3e]) ([Ww][0o]rd[5s])'  // 3 backreferences
];
for (var i in searches) {
    "Some string chars and many m0re w0rds in this test123".replace(
        new RegExp(
            searches[i]
            function(...args) {
                var match = args[0];
                var backrefs = args.slice(1, args.length - 2);
                // will be: ['Some', 'string'], ['many', 'm0re', 'w0rds'], ['123']
                var offset = args[args.length - 2];
                var string = args[args.length - 1];
            }
        )
    );
}

Bạn không thể sử dụng biến 'đối số' ở đây vì nó thuộc loại Arguments và không có loại nào Array vì vậy nó không có slice() phương pháp.


0
2017-07-05 14:45