Javascript Regex: จะวางตัวแปรในนิพจน์ปกติได้อย่างไร?


206

ตัวอย่างเช่น:

function(input){
    var testVar = input;
    string = ...
    string.replace(/ReGeX + testVar + ReGeX/, "replacement")
}

แต่แน่นอนว่าไม่ได้ผล :) มีวิธีการทำเช่นนี้หรือไม่?


11
โปรดทราบว่าหากคุณให้ผู้ใช้ระบุตัวแปรนี้ผู้ใช้ที่ประสงค์ร้ายอาจทำให้แอปพลิเคชันของคุณพังได้ง่าย ๆ ด้วยการย้อนรอยหายนะ
ทิม Pietzcker

2
"ReGeX" คืออะไร? มันเป็นชื่อตัวแปรหรือไม่? มันทำให้คำตอบสับสนโดยหมายความว่ามันเป็นส่วนหนึ่งของโครงสร้าง RegExp (ในกรณีที่ผู้อ่านไม่เห็นอักขระแปลก ๆ เหล่านั้นในคำถาม)
Eduard

คำตอบ:


272
const regex = new RegExp(`ReGeX${testVar}ReGeX`);
...
string.replace(regex, "replacement");

ปรับปรุง

ต่อความคิดเห็นบางส่วนจึงเป็นสิ่งสำคัญที่จะต้องทราบว่าคุณอาจต้องการที่จะหลบหนีตัวแปรถ้ามีที่มีศักยภาพสำหรับเนื้อหาที่เป็นอันตราย (เช่นตัวแปรมาจากการป้อนข้อมูลของผู้ใช้)

อัพเดต ES6

ในปี 2019 นี้มักจะเขียนโดยใช้แม่แบบสตริงและรหัสข้างต้นได้รับการปรับปรุง คำตอบเดิมคือ:

var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");

5
อย่าลืมสตริงของคุณ! ดู @zzzzBov คำตอบ
jtpereyda

นี้จะไม่ทำงานในกรณีของฉันคุณสามารถโปรดได้ดูjsfiddle นี้และแจ้งให้เราทราบว่าสิ่งที่ฉันต้องทำอย่างไรถ้าฉันต้องการตั้งค่าแบบไดนามิกรหัสประเทศเข้าสู่regexการแสดงออก
Kirankumar Dafda

10
สิ่งสำคัญที่ต้องจำก็คือในสตริงปกติ \ character จะต้องหลบหนีในขณะที่อยู่ในตัวอักษร regex (ปกติ) / ตัวอักษรจะต้องหลบหนี ดังนั้น/\w+\//iจะกลายเป็นnew RegExp("\\w+/", "i")
อาลี

3
วิธีการเกี่ยวกับ / g?
Qian Chen

พวกฉันต้องแยก regex นี้ / [^^0-9.-emb/g] โดยสองส่วน: / [^ 0-9 และ -] / g ทำอย่างไร?
สูงสุด

79

คุณสามารถใช้วัตถุ RegExp:

var regexstring = "whatever";
var regexp = new RegExp(regexstring, "gi");
var str = "whateverTest";
var str2 = str.replace(regexp, "other");
document.write(str2);

จากนั้นคุณสามารถสร้างregexstringในแบบที่คุณต้องการ

คุณสามารถอ่านเพิ่มเติมได้ที่นี่


var characterCount = parseInt (attrs.limitCharacterCount); console.log (characterCount); var specialCharactersValidation = new RegExp ("/ ^ [a-zA-Z0-9] {" + characterCount + "} $ /"); / \ / ^ [a-zA-Z0-9] {7} $ \ // requestShipmentDirectives.js: 76 main main.js false: 46 Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'offsetWidth' ของ null นี่คือสิ่งที่เกิดขึ้นเมื่อฉันทำ RegEx Dynamic
Ankit Tanna

31

ในการสร้างนิพจน์ทั่วไปจากตัวแปรใน JavaScript คุณจะต้องใช้RegExpConstructor กับพารามิเตอร์สตริง

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}

แน่นอนว่านี่เป็นตัวอย่างที่ไร้เดียงสามาก โดยถือว่าinputเป็นสิ่งที่ถูกหลบหนีอย่างเหมาะสมสำหรับการแสดงออกปกติ หากคุณจัดการกับการป้อนข้อมูลของผู้ใช้หรือเพียงแค่ต้องการความสะดวกในการจับคู่อักขระพิเศษคุณจะต้องหลีกเลี่ยงอักขระพิเศษ :

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

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    input = regexEscape(input);
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}

วิธีเดียวที่ใช้ได้ผลสำหรับฉันคือถ้าฉันลบReGeXข้อความ ดังนั้นฉันจึงใช้:return new RegExp(input, flags);
Michael Rader

2
@MichaelRader ใช่ข้อความ "ReGeX" เป็นส่วนหนึ่งของคำถามและใช้เป็นตัวอย่างไม่ใช่สิ่งที่ต้องใช้เพื่อให้โค้ดทำงาน
zzzzBov

1
ฮ่า ๆ เพิ่งรู้ว่าเป็นเพียงตัวยึดตำแหน่งของคุณ แต่เป็น noob นี้เอาฉันชั่วครู่เพื่อคิดออก ขอบคุณ
Michael Rader

ฉันเข้าใจว่าเหตุใดจึงต้องมีการหลีกเลี่ยงสตริง แต่ทำไมจึงใช้ '\\ $ &' ​​แทน
Sherin Binu

2
\\แสดงให้เห็นถึงซิงเกิ้ล\ของตัวละคร$&เป็น substring
zzzzBov

7

หากคุณใช้ตัวอักษรเทมเพลต es6 เป็นตัวเลือก ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")

มันใช้งานไม่ได้กับเทมเพลตตัวอักษร ฉันใช้ regexp เพื่อตรวจสอบรหัสผ่านในแอปของฉันและฉันต้องการกำหนดความยาวสูงสุดและต่ำสุดในสตริงนิพจน์ปกติของฉันและมันไม่ทำงาน `` `const newRegExp = new RegExp ( ^[^\s]{${4},${32}}$); ส่งออก const validatePassword = value => value.match (newRegExp); `` `
p7adams

6

"ReGeX" + testVar + "ReGeX"คุณสามารถให้การแสดงออกปกติเป็นสตริงคือ คุณอาจต้องหลีกเลี่ยงอักขระบางตัวที่อยู่ในสายอักขระ (เช่นอัญประกาศคู่) แต่โดยส่วนใหญ่แล้วจะเทียบเท่ากัน

คุณยังสามารถใช้ตัวRegExpสร้างเพื่อส่งผ่านค่าสถานะใน ( ดูเอกสาร )


3

คุณสามารถสร้างนิพจน์ทั่วไปใน JS ได้สองวิธี:

  1. ใช้การแสดงออกตามตัวอักษรปกติ - /ab{2}/g
  2. ใช้ตัวสร้างนิพจน์ทั่วไป - new RegExp("ab{2}", "g").

ตัวอักษรนิพจน์ปกติเป็นค่าคงที่และไม่สามารถใช้กับตัวแปรได้ สิ่งนี้สามารถทำได้โดยใช้ตัวสร้าง การแตกหักของตัวสร้าง RegEx คือ

new RegExp(regularExpressionString, modifiersString)

คุณสามารถฝังตัวแปรเป็นส่วนหนึ่งของ regularExpressionString ตัวอย่างเช่น,

var pattern="cd"
var repeats=3
new RegExp(`${pattern}{${repeats}}`, "g") 

สิ่งนี้จะตรงกับลักษณะของลวดลายcdcdcdใด ๆ


2

นี่คือฟังก์ชั่นที่ไร้ประโยชน์ซึ่งจะคืนค่าที่ห่อหุ้มด้วยอักขระเฉพาะ :)

jsfiddle: https://jsfiddle.net/squadjot/43agwo6x/

function getValsWrappedIn(str,c1,c2){
    var rg = new RegExp("(?<=\\"+c1+")(.*?)(?=\\"+c2+")","g"); 
    return str.match(rg);
    }

var exampleStr = "Something (5) or some time (19) or maybe a (thingy)";
var results =  getValsWrappedIn(exampleStr,"(",")")

// Will return array ["5","19","thingy"]
console.log(results)

2

คำตอบที่ยอมรับไม่ได้ผลสำหรับฉันและไม่ทำตามตัวอย่าง MDN

ดูส่วน 'คำอธิบาย' ในลิงค์ด้านบน

ฉันจะไปกับสิ่งต่อไปนี้ซึ่งได้ผลกับฉัน:

let stringThatIsGoingToChange = 'findMe';
let flagsYouWant = 'gi' //simple string with flags
let dynamicRegExp = new RegExp(`${stringThatIsGoingToChange}`, flagsYouWant)

// that makes dynamicRegExp = /findMe/gi

1
มันยังใช้งานได้ ปัญหาคือ 'ReGeX' + testVar + 'ReGeX' ทำให้การแก้ปัญหาเกิดความสับสน การเพิ่มตัวอย่างจริง ๆ จะทำให้สิ่งต่าง ๆ ในความคิดของฉันชัดเจน var testVar = '321'; var regex = new RegExp ("[" + testVar + "] {2}", "g"); // เหนือเทียบเท่ากับ / [321] {2} / g
HelloWorldPeace

1

มีความจำเป็นต้องเตรียมตัวแปรสตริงก่อนแล้วจึงแปลงเป็น RegEx

ตัวอย่างเช่น:

คุณต้องการเพิ่มminLengthและMaxLengthใช้ตัวแปร RegEx:

function getRegEx() {
    const minLength = "5"; // for exapmle: min is 5
    const maxLength = "12"; // for exapmle: man is 12

    var regEx = "^.{" + minLength + ","+ maxLength +"}$"; // first we make a String variable of our RegEx
    regEx = new RegExp(regEx, "g"); // now we convert it to RegEx

    return regEx; // In the end, we return the RegEx
}

ตอนนี้ถ้าคุณเปลี่ยนค่าของMaxLengthหรือMinLengthมันจะเปลี่ยนใน RegEx ทั้งหมด

หวังว่าจะเป็นประโยชน์ ขอโทษด้วยเกี่ยวกับภาษาอังกฤษของฉัน

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