JavaScript - chuỗi regex backreferences


93

Bạn có thể tham khảo lại như thế này trong JavaScript:

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

Điều này (khá ngớ ngẩn) sẽ thay thế "$ test" bằng "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, hàm này 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 "test", 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"));

Câu trả lời:


117

Như thế này:

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

1
Thật tuyệt, tôi có thể tìm thêm thông tin về điều này ở đâu?
quano


11
Mát mẻ. Để làm rõ: $1$2là tên tham số do người dùng chọn ở đây (được chọn để bắt chước các biểu tượng tham chiếu ngược); cái - khác nhau! - số lượng các tham số này tương ứng với số lượng nhóm bắt trong regex.
mklement0

34

Truyền một hàm làm đối số thứ hai cho replace:

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

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

Tính năng này đã có từ Javascript 1.3, theo mozilla.org .


1

Sử dụng ESNext, một trình thay thế các liên kết khá giả 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

Lưu ý: Câu trả lời trước thiếu một số mã. Nó hiện đã được sửa + ví dụ.


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

var text = "some string with an encoded '&#115;' in it";

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

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

0

Nếu bạn có một số lượng backreferences thay đổi thì số đối số (và vị trí) cũng có thể thay đổi. Các MDN Web Documents mô tả cú pháp follwing cho sepcifing một chức năng như là đối số thay thế:

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

Ví dụ: lấy các biểu thức chính quy 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ó có kiểu Argumentsvà không có kiểu Arraynên nó không có slice()phương thức.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.