Làm thế nào để bạn sử dụng một biến trong một biểu thức thông thường?


1380

Tôi muốn tạo một String.replaceAll()phương thức trong JavaScript và tôi nghĩ rằng sử dụng regex sẽ là cách tuyệt vời nhất để làm điều đó. Tuy nhiên, tôi không thể tìm ra cách chuyển một biến vào regex. Tôi có thể làm điều này đã thay thế tất cả các trường hợp "B"bằng "A".

"ABABAB".replace(/B/g, "A");

Nhưng tôi muốn làm một cái gì đó như thế này:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

Nhưng rõ ràng điều này sẽ chỉ thay thế văn bản "replaceThis"... vậy làm cách nào để chuyển biến này vào chuỗi regex của tôi?


9
Lưu ý rằng chúng tôi hiện đang làm việc để thêm chức năng này vào JavaScript nếu bạn có ý kiến ​​về nó, vui lòng tham gia thảo luận.
Benjamin Gruenbaum

Câu trả lời:


1842

Thay vì sử dụng /regex/gcú pháp, bạn có thể xây dựng một đối tượng RegExp mới :

var replace = "regex";
var re = new RegExp(replace,"g");

Bạn có thể tự động tạo các đối tượng regex theo cách này. Sau đó, bạn sẽ làm:

"mystring".replace(re, "newstring");

272
Nếu bạn cần sử dụng một biểu thức như thế nào /\/word\:\w*$/, hãy chắc chắn thoát khỏi dấu gạch chéo ngược của bạn : new RegExp( '\\/word\\:\\w*$' ).
Jonathan Swinney

2
@gravityboy Bạn có thể làm ('' + myNumber) .replace (/ 10 / g, 'a') hoặc nếu bạn muốn số hex, bạn có thể thực hiện parseInt ('' + myNumber, 16) để chuyển đổi thành hex từ thập phân.
Eric Wendelin

29
Câu hỏi gợi ý rằng RegEx chỉ được sử dụng để thực hiện thay thế chuỗi không đổi. Vì vậy, đây là câu trả lời sai vì nó sẽ thất bại nếu chuỗi chứa các ký tự meta RegEx. Đáng buồn là nó được bình chọn cao như vậy, sẽ khiến nhiều người đau đầu ...
dronus

16
Một ví dụ về việc vượt qua một biến này sẽ làm cho điều này trở thành một câu trả lời tốt. Tôi vẫn đang vật lộn sau khi đọc nó.
Ngỗng

3
@JonathanSwinney: /không có ý nghĩa đặc biệt nếu bạn xây dựng regex từ chuỗi, vì vậy bạn không cần phải thoát nó. /\/word\:\w*$/nên lànew RegExp('/word\\:\\w*$')
Dávid Horváth

211

Như Eric Wendelin đã đề cập, bạn có thể làm một cái gì đó như thế này:

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

Sản lượng này "regex matching .". Tuy nhiên, nó sẽ thất bại nếu str1 là ".". Bạn mong muốn kết quả sẽ "pattern matching regex"thay thế thời gian bằng "regex", nhưng nó sẽ trở thành ...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

Điều này là do, mặc dù "."là một Chuỗi, trong hàm tạo RegExp, nó vẫn được hiểu là một biểu thức chính quy, có nghĩa là bất kỳ ký tự không ngắt dòng nào, có nghĩa là mọi ký tự trong chuỗi. Đối với mục đích này, chức năng sau đây có thể hữu ích:

 RegExp.quote = function(str) {
     return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
 };

Sau đó, bạn có thể làm:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

năng suất "pattern matching regex".


4
Bạn có biết rằng tham số đầu tiên để thay thế có thể là một chuỗi bình thường và không phải là một biểu thức chính quy? str1 = "."; alert ("khớp mẫu.". thay thế (str1, "chuỗi"));
một số

@some: tất nhiên rồi. Đó là vì ví dụ trên là tầm thường. Ví dụ: khi bạn cần tìm kiếm hoặc thay thế một mẫu kết hợp với một chuỗi thông thường, hãy thực hiện str.match (RegExp mới ("https ?: //" + RegExp.escape (myDomainName)). không được xây dựng.
Gracenotes

(tiếp theo) Plus, rõ ràng JC Grubbs yêu cầu thay thế toàn cầu; việc thực hiện thay thế toàn cầu bằng String.replace (Chuỗi, Chuỗi) có thể chậm đối với đầu vào lớn. Tôi chỉ nói rằng, hai giải pháp hàng đầu là lỗi và sẽ không thành công ở đầu vào nhất định.
Gracenotes

4
developer.mozilla.org/en-US/docs/JavaScript/Guide/ khuyên cung cấp một chức năng tương tự, nhưng chúng loại trừ -và bao gồm =!:/.
chbrown

8
Thuật ngữ chính xác là "thoát", không phải "trích dẫn". Chỉ cần BTW.
Lawrence Dol

118

"ABABAB".replace(/B/g, "A");

Như mọi khi: không sử dụng regex trừ khi bạn phải. Đối với một chuỗi thay thế đơn giản, thành ngữ là:

'ABABAB'.split('B').join('A')

Sau đó, bạn không phải lo lắng về các vấn đề trích dẫn được đề cập trong câu trả lời của Gracenotes.


11
Và bạn có đo được rằng cái này nhanh hơn regex không?
Mitar

3
Điều này có vẻ thích hợp hơn, đặc biệt là khi cần khớp với các ký tự regex đặc biệt như '.'
Kreas

1
Uhm ... Không chia tách cũng mất RegExp; Nếu vậy, nó sẽ gây ra vấn đề tương tự? Dù sao ... .split (). Tham gia () có thể chậm hơn trên một số nền tảng, bởi vì đó là hai hoạt động, trong khi .replace () là một hoạt động và có thể được tối ưu hóa.

5
@ PacMan--: cả hai splitreplacecó thể lấy một chuỗi hoặc một RegExpđối tượng. Vấn đề mà replacecó mà splitkhông làm là khi bạn sử dụng một chuỗi bạn chỉ nhận được một sự thay thế duy nhất.
bobince


38

Nếu bạn muốn nhận TẤT CẢ các lần xuất hiện ( g), không phân biệt chữ hoa chữ thường ( i) và sử dụng các ranh giới để nó không phải là một từ trong một từ khác ( \\b):

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');

Thí dụ:

let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.

cảm ơn bạn! (afaict, của bạn là câu trả lời duy nhất rõ ràng với rxphép nội suy Emacs / kiểu, thông qua các chuỗi mẫu.)
sam boosalis

34

Đối với bất kỳ ai đang tìm cách sử dụng biến với phương thức khớp , điều này hiệu quả với tôi

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight


20
this.replace( new RegExp( replaceThis, 'g' ), withThis );

Tôi thích câu trả lời này vì nó không tạo ra biến (& vô nghĩa).
Bấc

14

Bạn muốn xây dựng biểu thức chính quy một cách linh hoạt và vì điều này, giải pháp thích hợp là sử dụng hàm new RegExp(string)tạo. Để constructor xử lý các ký tự đặc biệt theo nghĩa đen , bạn phải thoát chúng. Có một hàm dựng sẵn trong tiện ích tự động hoàn thành UI UI được gọi là $.ui.autocomplete.escapeRegex:

[...] Bạn có thể sử dụng $.ui.autocomplete.escapeRegexchức năng tích hợp. Nó sẽ lấy một đối số chuỗi đơn và thoát tất cả các ký tự regex, làm cho kết quả được chuyển đến an toàn new RegExp().

Nếu bạn đang sử dụng jQuery UI, bạn có thể sử dụng chức năng đó hoặc sao chép định nghĩa của nó từ nguồn :

function escapeRegex( value ) {
    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}

Và sử dụng nó như thế này:

"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
//            escapeRegex("[z-a]")       -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result                            -> "[a-z][a-z][a-z]"

9
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Kiểm tra với công cụ này


5
String.prototype.replaceAll = function(a, b) {
    return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}

Kiểm tra nó như sau:

var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))

4

Đây là một thay thế khác Thực hiện tất cả:

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if ( stringToFind == stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };

4

Và phiên bản cà phê của câu trả lời của Steven Penny, vì đây là kết quả số 2 của google .... ngay cả khi cà phê chỉ là javascript với rất nhiều ký tự bị xóa ...;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

và trong trường hợp cụ thể của tôi

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"

Tại sao một downvote? coffeescript -IS- javascript với cú pháp cụ thể của riêng nó.
quan tâm

robot.name=hubotkhông phải là javascript.
codepleb

3

Mặc dù bạn có thể tạo RegExp được tạo động (theo các câu trả lời khác cho câu hỏi này), tôi sẽ phản hồi nhận xét của tôi từ một bài đăng tương tự : Dạng chức năng của String.replace () rất hữu ích và trong nhiều trường hợp làm giảm nhu cầu về các đối tượng RegExp được tạo động. (đó là một nỗi đau 'vì bạn phải thể hiện đầu vào cho hàm tạo RegExp dưới dạng một chuỗi thay vì sử dụng dấu gạch chéo / [AZ] + / regrec định dạng bằng chữ)


3

Để đáp ứng nhu cầu của tôi, hãy chèn một biến / bí danh / hàm vào Biểu thức chính quy, đây là những gì tôi nghĩ ra:

oldre = /xx\(""\)/;
function newre(e){
    return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");

trong đó 'oldre' là biểu thức chính quy mà tôi muốn chèn một biến, 'xx' là trình giữ chỗ cho biến / bí danh / hàm đó và 'yy' là tên biến, bí danh hoặc hàm thực tế.


2

Bạn có thể sử dụng điều này nếu $ 1 không hoạt động với bạn

var pattern = new RegExp("amman","i");
"abc Amman efg".replace(pattern,"<b>"+"abc Amman efg".match(pattern)[0]+"</b>");

1

Bạn luôn có thể sử dụng indexOfnhiều lần:

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

Điều này không đi vào một vòng lặp vô hạn khi sự thay thế có chứa sự phù hợp.


1

Giải pháp của bạn là đây:

Truyền một biến cho biểu thức chính quy.

Cái mà tôi đã triển khai là bằng cách lấy giá trị từ trường văn bản là trường bạn muốn thay thế và trường khác là trường văn bản "thay thế bằng", lấy giá trị từ trường văn bản trong một biến và đặt biến thành RegExp chức năng để tiếp tục thay thế. Trong trường hợp của tôi, tôi đang sử dụng Jquery, bạn cũng có thể làm điều đó chỉ bằng JavaScript.

Mã JavaScript:

  var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replace
  var replace_with = document.getElementById("with"); //Getting the value from another text fields with which I want to replace another string.

  var sRegExInput = new RegExp(replace, "g");    
  $("body").children().each(function() {
    $(this).html($(this).html().replace(sRegExInput,replace_with));
  });

Mã này nằm trong sự kiện Onclick của một nút, bạn có thể đặt mã này trong một chức năng để gọi.

Vì vậy, bây giờ bạn có thể vượt qua biến trong chức năng thay thế.


Biến thay thế của bạn sẽ chứa phần tử DOM chứ không phải chính giá trị
Ben Taliadoros

1

Hàm tự gọi này sẽ lặp lại trên replacerItems bằng cách sử dụng một chỉ mục và thay đổi replacerItems [index] trên toàn cầu trên mỗi chuỗi.

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'

0

Không có câu trả lời nào trong số này rõ ràng với tôi. Cuối cùng tôi đã tìm thấy một lời giải thích tốt tại http://burnignorance.com/php-programming-tips/how-to-use-a-variable-in-replace-feft-of-javascript/

Câu trả lời đơn giản là:

var search_term = new RegExp(search_term, "g");    
text = text.replace(search_term, replace_term);

Ví dụ:

$("button").click(function() {
  Find_and_replace("Lorem", "Chocolate");
  Find_and_replace("ipsum", "ice-cream");
});

function Find_and_replace(search_term, replace_term) {
  text = $("textbox").html();
  var search_term = new RegExp(search_term, "g");
  text = text.replace(search_term, replace_term);
  $("textbox").html(text);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>


1
Bạn đang ghi đè một biến đóng, không cần sử dụng varở đây. Ngoài ra, nếu bạn vượt qua \bhoặc \1nó sẽ phá vỡ.
CyberAP

0

Để thay thế nhiều mà không có biểu thức chính quy, tôi đã làm như sau:

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

Phần quan trọng của giải pháp đã được tìm thấy ở đây

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.