Sử dụng chuỗi động (biến) làm mẫu regex trong JavaScript


101

Tôi muốn thêm thẻ (biến) vào các giá trị bằng regex, mẫu hoạt động tốt với PHP nhưng tôi gặp sự cố khi triển khai nó vào JavaScript.

Mẫu là ( valuelà biến):

/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is

Tôi đã thoát khỏi các dấu gạch chéo ngược:

var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "<a href='#" + value +">" + value + "</a>"));

Nhưng điều này có vẻ không đúng, tôi đã ghi lại mô hình và chính xác nó phải như thế nào. Bất kỳ ý tưởng?


valuemột biến?
Dogbert

Câu trả lời:


173

Để tạo regex từ một chuỗi, bạn phải sử dụng đối tượng của JavaScriptRegExp .

Nếu bạn cũng muốn để phù hợp với / thay thế nhiều hơn một lần, sau đó bạn phải thêm các g(trận đấu toàn cầu) cờ . Đây là một ví dụ:

var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

Bản demo JSFiddle tại đây.


Trong trường hợp chung, hãy thoát khỏi chuỗi trước khi sử dụng dưới dạng regex:

Tuy nhiên, không phải mọi chuỗi đều là regex hợp lệ: có một số ký tự đặc biệt, như (hoặc [. Để khắc phục sự cố này, chỉ cần thoát khỏi chuỗi trước khi chuyển nó thành regex. Một chức năng tiện ích cho điều đó có trong ví dụ dưới đây:

function escapeRegExp(stringToGoIntoTheRegex) {
    return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

Bản demo JSFiddle tại đây.



Lưu ý: regex trong câu hỏi sử dụng công cụ ssửa đổi, không tồn tại vào thời điểm câu hỏi, nhưng tồn tại - một cờ s( dotall ) / sửa đổi trong JavaScript - ngày nay .


2
điều này thật tuyệt và là ví dụ tốt nhất mà tôi đã tìm thấy cho đến nay về việc sử dụng một biến động trong regex, cảm ơn!
Eolis

1
Đối với năm 2019 s bổ sung, hãy xem lại liên kết MDN trong ghi chú của câu trả lời.
Nickensoul

@Nickensoul Chà! Cảm ơn cho những người đứng đầu lên!
acdcjunior

let idr = new RegExp (biến + "$"); Table.find ({field: new RegExp (idr, 'i')}) Tôi đã làm như thế này. Chúc mừng.
Utkarsh

12

Nếu bạn đang cố gắng sử dụng một giá trị biến trong biểu thức, bạn phải sử dụng "hàm tạo" RegExp.

var regex="(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")

6

Bạn không cần "xác định một biểu thức chính quy vì vậy chỉ cần:

var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax

Nếu valuelà một biến và bạn muốn một biểu thức chính quy động thì bạn không thể sử dụng ký hiệu này; sử dụng ký hiệu thay thế.

String.replace cũng chấp nhận chuỗi làm đầu vào, vì vậy bạn có thể làm "fox".replace("fox", "bear");

Thay thế:

var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");

Hãy nhớ rằng nếu valuechứa các ký tự biểu thức chính quy như (, [?bạn sẽ cần phải thoát chúng.


2
Các tùy chọn đầu tiên sẽ không làm việc trừ khi tìm kiếm chuỗi "giá trị"
mothmonsterman

@happytimeharry Có vẻ như có xung đột giữa hai regexps mà anh ấy đã đăng.
Halcyon

@Fritz van Campen có vẻ như mục đích của mô hình, đưa ra ví dụ từ javascript của mình, là sử dụng một biến
mothmonsterman

cùng một vấn đề ở đây, dường như có một cái gì đó sai với "là" lá cờ: "của router Lỗi Cú pháp: cờ không hợp lệ cung cấp cho RegExp constructor 'là'"
Borstenhorst

các cờ cho phương thức khởi tạo của RegExp cần phải được tách biệt. Nhưng regex vẫn không hoạt động.
Borstenhorst

5

Tôi thấy chủ đề này hữu ích - vì vậy tôi nghĩ rằng tôi sẽ thêm câu trả lời cho vấn đề của riêng mình.

Tôi muốn chỉnh sửa tệp cấu hình cơ sở dữ liệu (datastax cassandra) từ ứng dụng nút trong javascript và đối với một trong các cài đặt trong tệp mà tôi cần khớp trên một chuỗi và sau đó thay thế dòng theo sau nó.

Đây là giải pháp của tôi.

dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'

// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
    // need to use double escape '\\' when putting regex in strings !
    var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
    var myRegExp = new RegExp(searchString + re, "g");
    var match = myRegExp.exec(data);
    var replaceThis = match[1];
    var writeString = data.replace(replaceThis, newString);
    fs.writeFile(file, writeString, 'utf-8', function (err) {
    if (err) throw err;
        console.log(file + ' updated');
    });
});
}

searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"

replaceStringNextLine(dse_cassandra_yaml, searchString, newString );

Sau khi chạy, nó sẽ thay đổi cài đặt thư mục dữ liệu hiện có thành cài đặt mới:

tập tin cấu hình trước:

data_file_directories:  
   - /var/lib/cassandra/data

tập tin cấu hình sau:

data_file_directories:  
- /mnt/cassandra/data

4

Tôi thấy mình phải gạch chéo hai lần \ b để nó hoạt động. Ví dụ: để xóa các từ "1x" khỏi chuỗi bằng một biến, tôi cần sử dụng:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");

Đã làm cho tôi. Cảm ơn,
Pravin Bhapkar

1

Cách dễ dàng hơn nhiều: sử dụng các ký tự mẫu.

var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false

0
var string = "Hi welcome to stack overflow"
var toSearch = "stack"

//case insensitive search

var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'

https://jsfiddle.net/9f0mb6Lz/

Hi vọng điêu nay co ich

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.