2013-07-26 34 views
33

Tôi muốn thêm thẻ (biến) vào giá trị bằng regex, mẫu hoạt động tốt với PHP nhưng tôi gặp khó khăn khi triển khai JavaScript.Sử dụng chuỗi động (biến) làm mẫu regex trong JavaScript

Các mô hình là (value là biến):

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

tôi thoát khỏi những dấu xồ nguợ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 dường như không thể đúng, tôi đăng nhập mô hình và nó chính xác những gì nó nên là. Bất kỳ ý tưởng nào?

+0

Giá trị 'có phải là một biến không? – Dogbert

Trả lời

77

Để tạo regex làm chuỗi, bạn phải sử dụng JavaScript's RegExp object.

Ngoài ra, bạn có thể muốn khớp/thay thế nhiều lần. Trong trường hợp đó, hãy thêm the g (global match) flag. Dưới đâ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. 

JSFiddle demo here.


Trong trường hợp tổng quát, thoát khỏi chuỗi trước khi sử dụng như regex:

Không phải mọi chuỗi là một regex hợp lệ, mặc dù: có một số ký tự đặc biệt, như ( hoặc [. Để làm việc xung quanh vấn đề này, chỉ cần thoát khỏi chuỗi trước khi biến nó thành một regex. Một chức năng tiện ích cho mà đi trong mẫu 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. 

JSFiddle demo here.


Đối với trường hợp cụ thể trong câu hỏi, hãy chú ý there is no s (dotall) flag/modifier in JavaScript. Trường hợp nó có sẵn, nó thường buộc các dấu chấm (.) để phù hợp với dòng mới.Dưới đây là một giải pháp khả thi cho trường hợp của bạn:

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

Thông báo Tôi đã thêm một thiếu ' vào cuối "<a href='#" + value +"'>".

See demo fiddle here. Bạn cũng có thể muốn thử this solution using the "g" modifier.

+0

Cảm ơn, điều đó đã làm việc – Borstenhorst

+1

điều này thật tuyệt vời và ví dụ điển hình nhất mà Ive đã tìm thấy cho đến nay khi sử dụng biến số động trong regex, cảm ơn! – Eolis

2

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 value là một biến và bạn muốn có một biểu hiện thường xuyên động thì bạn không thể sử dụng ký hiệu này; sử dụng ký pháp thay thế.

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

Alternative:

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 ghi nhớ rằng nếu value chứa biểu thức ký tự thông thường như (, [? bạn sẽ cần phải thoát khỏi chúng.

+1

Tùy chọn đầu tiên sẽ không hoạt động trừ khi tìm kiếm chuỗi "giá trị" –

+0

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

+0

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

8

Nếu bạn đang cố gắng sử dụng 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") 
2

Tôi thấy chuỗi này hữu ích - vì vậy tôi nghĩ 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à cho một trong các cài đặt trong tệp tôi cần để khớp trên chuỗi và sau đó thay thế dòng sau.

Đâ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ác thiết lập hiện thư mục dữ liệu vào 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 
Các vấn đề liên quan