ใช้สตริง (ตัวแปร) แบบไดนามิกเป็นรูปแบบนิพจน์ทั่วไปใน JavaScript


114

ฉันต้องการเพิ่มแท็ก (ตัวแปร)ให้กับค่าด้วย regex รูปแบบนี้ใช้ได้ดีกับ PHP แต่ฉันมีปัญหาในการนำไปใช้กับ JavaScript

รูปแบบคือ ( valueคือตัวแปร):

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

ฉันหนีแบ็กสแลช:

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

แต่ดูเหมือนจะไม่ถูกต้องฉันบันทึกรูปแบบและสิ่งที่ควรจะเป็น ความคิดใด ๆ ?


คือvalueตัวแปร?
Dogbert

คำตอบ:


197

ในการสร้าง regex จากสตริงคุณต้องใช้ออบเจ็กต์ของ JavaScriptRegExpวัตถุ

หากคุณยังต้องการที่จะตรง / แทนที่มากกว่าหนึ่งครั้งแล้วคุณจะต้องเพิ่ม(การแข่งขันทั่วโลก) ธง นี่คือตัวอย่าง:g

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 สาธิตที่นี่


ในกรณีทั่วไปให้หลีกเลี่ยงสตริงก่อนที่จะใช้เป็น regex:

ไม่ใช่ว่าทุกคนเป็นสตริง regex ถูกต้องแม้ว่า: มีบางตัวละคร speciall เหมือนหรือ( [เมื่อต้องการหลีกเลี่ยงปัญหานี้เพียงแค่หลีกเลี่ยงสตริงก่อนที่จะเปลี่ยนเป็นนิพจน์ทั่วไป ฟังก์ชั่นยูทิลิตี้ที่อยู่ในตัวอย่างด้านล่าง:

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 สาธิตที่นี่



หมายเหตุ: regex ในคำถามใช้sปรับปรุงซึ่งไม่ได้อยู่ในช่วงเวลาของคำถามที่แต่ไม่อยู่ - s( dotall ) ธง / ปรับปรุงใน JavaScript - วันนี้


2
นี่เป็นตัวอย่างที่ดีและเป็นตัวอย่างที่ดีที่สุดที่ฉันเคยพบในการใช้ตัวแปรไดนามิกใน regex ขอบคุณ!
Eolis

1
สำหรับปี 2019 มี sตัวปรับแต่งโปรดดูลิงก์ MDN อีกครั้งในหมายเหตุของคำตอบ
Nickensoul

@Nickensoul เห็นดี! ขอบคุณสำหรับหัวขึ้น!
acdcjunior

ให้ idr = RegExp ใหม่ (ตัวแปร + "$"); Table.find ({field: new RegExp (idr, 'i')}) ฉันทำแบบนี้ ไชโย
Utkarsh


7

คุณไม่จำเป็นต้อง"กำหนดนิพจน์ทั่วไปเพียงแค่:

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

ถ้า valueเป็นตัวแปรและคุณต้องการนิพจน์ทั่วไปแบบไดนามิกคุณจะไม่สามารถใช้สัญกรณ์นี้ได้ ใช้สัญกรณ์อื่น

String.replace ยังยอมรับสตริงเป็นอินพุตดังนั้นคุณสามารถทำได้ "fox".replace("fox", "bear");

ทางเลือก:

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");

เก็บไว้ในใจว่าถ้าvalueมีการแสดงออกปกติตัวละครชอบ(, [และ?คุณจะต้องหลบหนีพวกเขา


2
ตัวเลือกแรกจะใช้ไม่ได้เว้นแต่จะมองหาสตริง "value"
mothmonsterman

@happytimeharry ดูเหมือนจะมีความขัดแย้งระหว่าง regexps ทั้งสองที่เขาโพสต์
Halcyon

@Fritz van Campen ดูเหมือนว่าเจตนาของรูปแบบที่ได้รับจากตัวอย่างจากจาวาสคริปต์ของเขาคือการใช้ตัวแปร
mothmonsterman

ปัญหาเดียวกันที่นี่ดูเหมือนว่าจะมีบางอย่างผิดปกติกับแฟล็ก "is": "Uncaught SyntaxError: แฟล็กที่ไม่ถูกต้องที่ส่งไปยังตัวสร้าง RegExp" คือ ""
Borstenhorst

แฟล็กสำหรับคอนสตรัคเตอร์ของ RegExp จำเป็นต้องแยกออกจากกัน แต่ regex ยังไม่ทำงาน
Borstenhorst

5

ฉันพบว่ากระทู้นี้มีประโยชน์ - ฉันจึงคิดว่าจะเพิ่มคำตอบให้กับปัญหาของตัวเอง

ฉันต้องการแก้ไขไฟล์คอนฟิกูเรชันฐานข้อมูล (datastax cassandra) จากแอปพลิเคชันโหนดในจาวาสคริปต์และสำหรับการตั้งค่าอย่างใดอย่างหนึ่งในไฟล์ฉันต้องการจับคู่กับสตริงแล้วแทนที่บรรทัดที่ตามมา

นี่คือทางออกของฉัน

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 );

หลังจากรันมันจะเปลี่ยนการตั้งค่าไดเร็กทอรีข้อมูลที่มีอยู่เป็นไดเร็กทอรีใหม่:

config ไฟล์ก่อน:

data_file_directories:  
   - /var/lib/cassandra/data

ไฟล์ config หลังจาก:

data_file_directories:  
- /mnt/cassandra/data

5

ฉันพบว่าฉันต้องเฉือน \ b สองครั้งเพื่อให้มันใช้งานได้ ตัวอย่างเช่นในการลบคำ "1x" ออกจากสตริงโดยใช้ตัวแปรฉันต้องใช้:

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

ทำงานให้ฉัน ขอบคุณ
Pravin Bhapkar


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.