Regex để thay thế nhiều không gian bằng một không gian duy nhất


510

Đưa ra một chuỗi như:

"Con chó có một cái đuôi dài, và nó ĐỎ!"

Loại ma thuật jQuery hoặc JavaScript nào có thể được sử dụng để giữ khoảng trắng ở mức tối đa một không gian?

Mục tiêu:

"Con chó có một cái đuôi dài, và nó ĐỎ!"

4
Bạn cũng muốn khớp các ký tự tab trắng?
Nông dân Chris

@Chris, vâng, xin vui lòng, câu hỏi tuyệt vời .... Với tất cả những câu trả lời khác nhau này, làm thế nào để có thể biết đâu là giải pháp hiệu quả nhất?
AnApprentice

2
Mọi người dưới đây đều đúng, nhưng đây là regex được tối ưu hóa nhất: str.replace(/ +(?= )/g,'');bạn không thay thế bất cứ thứ gì bạn không phải làm.
Evan Carroll

2
Sẽ không có bất kỳ sự khác biệt đáng chú ý trong hiệu suất. Bạn luôn có thể hồ sơ nó, nhưng tôi nghi ngờ nó sẽ có giá trị nó. Tôi sẽ đi cho rõ ràng nhất.
Draemon

@EvanCarroll: Không đúng - ít nhất là trên Firefox. Phiên bản đó chạy chậm hơn đáng kể. Xem kết quả hồ sơ trong câu trả lời của tôi (bên dưới).
Edward Loper

Câu trả lời:


937

Cho rằng bạn cũng muốn bao gồm các tab, dòng mới, v.v., chỉ cần thay thế \s\s+bằng ' ':

string = string.replace(/\s\s+/g, ' ');

Nếu bạn thực sự muốn chỉ bao gồm các khoảng trắng (và do đó không phải là tab, dòng mới, v.v.), hãy làm như vậy:

string = string.replace(/  +/g, ' ');

4
Bạn cũng cần thêm cờ 'g' vào biểu thức chính quy.
Rafael

6
Điều này không hoạt động khi cần một khoảng trống thay vì một tab hoặc dòng mới. Đúng? / \ s + / sẽ hoạt động.
Fabian

3
nó có thể tốt hơn cho bạn như là một chức năng nhưfunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
làm lạnh toán học

5
@Ethan: JS có hàm dựng sẵn cho điều đó : trim(). Nó nhanh hơn regex. Bạn chỉ có thể làm string.trim().replace(/\s\s+/g, ' ');hoặc string.replace(/\s\s+/g, ' ').trim();.
BalusC

4
/\s\s+/g/\s{2,}/gkhông khớp các ký tự khoảng trắng trừ khi có ít nhất hai ký tự liền kề nhau, ví dụ: sẽ khớp với \ t \ t nhưng sẽ không khớp với một \ t. string.replace(/\s+/g, ' ')sẽ phù hợp với tất cả các chuỗi ký tự đơn và nhiều khoảng trắng và thay thế bằng không gian đơn.
remyActual

159

Vì bạn có vẻ hứng thú với hiệu suất, tôi đã mô tả những thứ này bằng con bọ lửa. Đây là kết quả tôi nhận được:

str.replace( /  +/g, ' ' )       ->  380ms
str.replace( /\s\s+/g, ' ' )     ->  390ms
str.replace( / {2,}/g, ' ' )     ->  470ms
str.replace( / +/g, ' ' )        ->  790ms
str.replace( / +(?= )/g, ' ')    -> 3250ms

Đây là trên Firefox, chạy thay thế chuỗi 100k.

Tôi khuyến khích bạn thực hiện các bài kiểm tra hồ sơ của riêng bạn với fireorms, nếu bạn nghĩ rằng hiệu suất là một vấn đề. Con người nổi tiếng là xấu khi dự đoán những điểm nghẽn trong chương trình của họ nằm ở đâu.

(Ngoài ra, lưu ý rằng thanh công cụ dành cho nhà phát triển của IE 8 cũng có một trình tạo hồ sơ được tích hợp sẵn - có thể đáng để kiểm tra hiệu năng trong IE.)


5
jsperf.com/removing-multipl-spaces Đi ra và JSPerf! Phương pháp cuối cùng; ( / +(?= )/g, ' ');thất bại trong IE9, nó để lại hai khoảng trắng: "Foo Bar Baz".replace(/ +(?= )/g, ' ');->"Foo Bar Baz"
Nenotlep

làm thế nào có nhiều diff bw 1 và 2nd line
Vivek Panday

@VivekPanday - Tôi tưởng tượng rằng điều này là do dòng thứ hai chỉ thay thế các lần xuất hiện của không gian đôi bằng một không gian duy nhất, trong khi dòng đầu tiên cũng thay thế bất kỳ không gian nào bằng một khoảng trắng. Cho dù đây là thời gian tiết kiệm trong quá trình tìm kiếm hoặc thay thế thực tế, tôi không biết.
Maloric

Điều này không loại bỏ các khoảng trắng ban đầu và dấu. Cho rằng xem câu trả lời này .
Ethan

Chỉnh sửa để đặt hàng bằng cách giảm tốc độ. Nhận xét của Vivek và Maloric đề cập đến các dòng với 380 ms và 790 ms.
Skippy le Grand Gourou

43
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

EDIT: Nếu bạn muốn thay thế tất cả các loại ký tự khoảng trắng, cách hiệu quả nhất sẽ là như thế:

str = str.replace(/\s{2,}/g,' ');

Buồn cười chuỗi thử nghiệm của bạn thậm chí không có hai khoảng trống trong đó.
Josh Stodola

chỉ cần nhận ra rằng bạn đã có những gì tôi đã đưa ra gần đây, +1 :)
meder omuraliev

2
Vì một số lý do, điều này không hoạt động ... Rất nhiều "& nbsp;" đang hiển thị ... Có khả năng là do CKEDITOR ...
AnApprentice

K hóa ra văn bản của JQUERY () đã làm mọi thứ rối tung lên. đã sửa - cảm ơn tất cả!
AnApprentice

16

Đây là một giải pháp, mặc dù nó sẽ nhắm mục tiêu tất cả các ký tự không gian:

"The      dog        has a long tail,      and it is RED!".replace(/\s\s+/g, ' ')

"The dog has a long tail, and it is RED!"

Chỉnh sửa : Điều này có thể tốt hơn vì nó nhắm mục tiêu một không gian theo sau bởi 1 hoặc nhiều khoảng trắng:

"The      dog        has a long tail,      and it is RED!".replace(/  +/g, ' ')

"The dog has a long tail, and it is RED!"

Phương pháp thay thế:

"The      dog        has a long tail,      and it is RED!".replace(/ {2,}/g, ' ')
"The dog has a long tail, and it is RED!"

Tôi đã không sử dụng /\s+/chính nó vì nó thay thế các không gian kéo dài 1 ký tự nhiều lần và có thể kém hiệu quả hơn vì nó nhắm mục tiêu nhiều hơn mức cần thiết.

Tôi đã không kiểm tra sâu bất kỳ trong số này vì vậy lmk nếu có lỗi.

Ngoài ra, nếu bạn định thay thế chuỗi, hãy nhớ gán lại biến / thuộc tính cho thay thế của chính nó, ví dụ:

var string = 'foo'
string = string.replace('foo', '')

Sử dụng jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )

1
Cái đầu tiên hoàn toàn vô nghĩa, \ s \ s + có nghĩa là, một \ s được theo sau bởi một hoặc nhiều \ s +, có thể rút gọn thành một \ s +, ví dụ thứ hai chính xác hơn vì chúng tôi chỉ muốn thay thế khoảng trắng kép, không phải dòng mới, thứ ba được tối ưu hóa hơn vì nó chỉ áp dụng cho các ví dụ có hơn 2 không gian. Nhưng str.replace (/ + (? =) / G, '');, chỉ áp dụng cho các ví dụ có hơn 2 khoảng trắng nhưng tiết kiệm ghi đè một khoảng trắng bằng một bước khoảng trắng.
Evan Carroll

4
EvanCarroll bạn thất bại vì \ s \ s + chắc chắn khác với \ s +. \ s \ s + sẽ khớp với '\ t \ t' hoặc '\ t \ t \ t' nhưng KHÔNG '\ t'. Và đó là tất cả những gì về nó, bạn không muốn thay thế mọi ký tự khoảng trắng đơn lẻ.
watain

Tôi làm. Được sử dụng cho tìm kiếm toàn văn bản (và hiển thị đoạn trích): Vui lòng không có tab ngẫu nhiên, không ngắt hoặc thingymajigs.
T4NK3R

13

Tôi có phương pháp này, tôi gọi nó là phương pháp Derp vì thiếu tên tốt hơn.

while (str.indexOf("  ") !== -1) {
    str = str.replace(/  /g, " ");
}

Chạy nó trong JSPerf cho một số kết quả đáng ngạc nhiên.


2
Tôi sẽ bối rối như địa ngục nếu hóa ra tôi đã làm hỏng trường hợp thử nghiệm thay vì nó thực sự nhanh: D
Nenotlep

Cung cấp một trường hợp thử nghiệm ... Câu trả lời tuyệt vời!
Oytun

2
Điều này làm cho ngày của tôi :-) Thật buồn cười là "derping" thường hoạt động tốt hơn tất cả "thông minh". "Derp split" dường như đã đá vào mông của nó mặc dù. Tuy nhiên, xứng đáng nâng cao.
Fred Gandt

13

Một phương pháp mạnh mẽ hơn: Điều này cũng quan tâm đến việc loại bỏ các không gian ban đầu và dấu, nếu chúng tồn tại. Ví dụ:

// NOTE the possible initial and trailing spaces
var str = "  The dog      has a long   tail, and it     is RED!  "

str = str.replace(/^\s+|\s+$|\s+(?=\s)/g, "");

// str -> "The dog has a long tail, and it is RED !"

Ví dụ của bạn không có những không gian đó nhưng chúng cũng là một kịch bản rất phổ biến và câu trả lời được chấp nhận chỉ là cắt xén chúng thành các không gian duy nhất, như: "... ĐỎ!", Đó không phải là điều bạn thường cần.


3
Tôi đã sử dụng mô hình này trên PHP và hoạt động. $ phần = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro

11

Mạnh mẽ hơn:

chức năng cắt (từ)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // thay đổi ký tự không in thành dấu cách
    trả về word.replace (/ ^ \ s + | \ s + $ / g, ''); // xóa khoảng trắng hàng đầu / dấu
}

8

Tôi đề nghị

string = string.replace(/ +/g," ");

chỉ cho không gian
HOẶC

string = string.replace(/(\s)+/g,"$1");

để biến nhiều lợi nhuận thành một lợi nhuận duy nhất cũng có.


6

Tôi biết rằng tôi đến bữa tiệc muộn, nhưng tôi đã khám phá ra một giải pháp tốt đẹp.

Đây là:

var myStr = myStr.replace(/[ ][ ]*/g, ' ');

6

Đây là một giải pháp thay thế nếu bạn không muốn sử dụng thay thế (thay thế khoảng trắng trong chuỗi mà không sử dụng thay thế javascript)

var str="The dog      has a long   tail, and it     is RED!";
var rule=/\s{1,}/g;
str = str.split(rule).join(" "); 
document.write(str);

5

Câu trả lời toàn diện không được mã hóa cho người mới và cộng sự.

Điều này là dành cho tất cả những người giả như tôi, người kiểm tra các kịch bản được viết bởi một số bạn không làm việc.

3 ví dụ sau đây là các bước tôi đã thực hiện để xóa các ký tự đặc biệt VÀ khoảng trắng thừa trên 3 trang web sau (tất cả đều hoạt động hoàn hảo) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com} vì vậy tôi biết rằng những thứ này hoạt động hoàn hảo.

Chúng tôi đã kết nối những thứ này cùng với hơn 50 cùng một lúc và KHÔNG gặp vấn đề gì.

// Điều này đã loại bỏ các ký tự đặc biệt + 0-9 và chỉ cho phép các chữ cái (chữ hoa và chữ LOWER)

function NoDoublesPls1()
{
var str=document.getElementById("NoDoubles1");
var regex=/[^a-z]/gi;
str.value=str.value.replace(regex ,"");
}

// Điều này đã loại bỏ các ký tự đặc biệt và chỉ cho phép các chữ cái (chữ hoa và chữ LOWER) và 0-9 VÀ khoảng trắng

function NoDoublesPls2()
{
var str=document.getElementById("NoDoubles2");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"");
}

// Điều này đã loại bỏ các ký tự đặc biệt và chỉ cho phép các chữ cái (chữ hoa và chữ LOWER) và 0-9 AND dấu cách // .replace (/ \ s \ s + / g, "") ở cuối sẽ loại bỏ khoảng trắng quá mức // khi tôi sử dụng dấu ngoặc đơn, nó không hoạt động.

function NoDoublesPls3()
{    var str=document.getElementById("NoDoubles3");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"") .replace(/\s\s+/g, " ");
}

:: NEXT :: Lưu # 3 là a .js// Tôi đã gọi tôi là NoD đúp.js

:: NEXT :: Bao gồm JS của bạn vào trang của bạn

 <script language="JavaScript" src="js/NoDoubles.js"></script>

Bao gồm điều này trong trường mẫu của bạn :: chẳng hạn như

<INPUT type="text" name="Name"
     onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Vì vậy mà nó trông như thế này

<INPUT type="text" name="Name" onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Điều này sẽ loại bỏ các ký tự đặc biệt, cho phép các khoảng trắng đơn và loại bỏ các khoảng trắng thừa.


Chuyện gì đang xảy ra ở đây? Các định dạng trông rất, rất bị hỏng.
Nenotlep


1
var string = "The dog      has a long   tail, and it     is RED!";
var replaced = string.replace(/ +/g, " ");

Hoặc nếu bạn cũng muốn thay thế các tab:

var replaced = string.replace(/\s+/g, " ");

1
sử dụng + có vẻ sạch hơn nhưng nó cũng sẽ thay thế các không gian đơn bằng các không gian đơn lẻ, một chút dư thừa và tôi không chắc nhưng nó có thể tạo ra các vấn đề về hiệu suất với văn bản dài hơn nhiều.
ahmetunal

Tôi có xu hướng sử dụng giải pháp ngắn nhất, đơn giản nhất sẽ hoạt động và chỉ lo lắng về loại tối ưu hóa đó nếu tôi biết rằng tôi cần phải khớp với một chuỗi rất lớn, tại thời điểm đó tôi sẽ thực sự đo các giải pháp khác nhau để xem cái nào sẽ Nhanh hơn. Có thể khó dự đoán trước những gì sẽ nhanh nhất mà không cần kiểm tra; chẳng hạn, trong trình thông dịch JavaScript, một số biểu thức chính quy phức tạp sẽ khiến bạn chuyển từ triển khai được biên dịch JIT nhanh sang phiên dịch chậm.
Brian Campbell

1

Jquery có chức năng trim () về cơ bản biến một cái gì đó giống như "Thanh FOo" này thành "Thanh FOo".

var string = "  My     String with  Multiple lines    ";
string.trim(); // output "My String with Multiple lines"

Nó hữu ích hơn nhiều vì nó cũng tự động loại bỏ các khoảng trống ở đầu và cuối chuỗi. Không cần regex.


3
Như bạn đã nói, trim () xóa các khoảng trống ở đầucuối chuỗi, nhưng không ở giữa chuỗi, vì vậy, nó không hoạt động trong trường hợp này, đầu ra sẽ chỉ là "Chuỗi của tôi có nhiều dòng ". api.jquery.com/jQuery.trim
egvaldes

1

được thay thế không được sử dụng, string = string.split (/ \ W + /);


0
var myregexp = new RegExp(/ {2,}/g);

str = str.replace(myregexp,' ');

0

Chúng ta có thể sử dụng regex sau đây được giải thích với sự trợ giúp của lệnh hệ thống sed. Regex tương tự có thể được sử dụng trong các ngôn ngữ và nền tảng khác.

Thêm văn bản vào một số tập tin nói thử nghiệm

manjeet-laptop:Desktop manjeet$ cat test
"The dog      has a long   tail, and it     is RED!"

Chúng ta có thể sử dụng regex sau để thay thế tất cả các khoảng trắng bằng một khoảng trắng

manjeet-laptop:Desktop manjeet$ sed 's/ \{1,\}/ /g' test
"The dog has a long tail, and it is RED!"

Hy vọng điều này phục vụ mục đích


0

Hãy thử điều này để thay thế nhiều không gian bằng một không gian duy nhất.

<script type="text/javascript">
    var myStr = "The dog      has a long   tail, and it     is RED!";
    alert(myStr);  // Output 'The dog      has a long   tail, and it     is RED!'

    var newStr = myStr.replace(/  +/g, ' ');
    alert(newStr);  // Output 'The dog has a long tail, and it is RED!'
</script>

Đọc thêm @ Thay thế nhiều không gian bằng một không gian


0
var text = `xxx  df dfvdfv  df    
                     dfv`.split(/[\s,\t,\r,\n]+/).filter(x=>x).join(' ');

kết quả:

"xxx df dfvdfv df dfv"

0

Để kiểm soát nhiều hơn, bạn có thể sử dụng gọi lại thay thế để xử lý giá trị.

value = "tags:HUNT  tags:HUNT         tags:HUNT  tags:HUNT"
value.replace(new RegExp(`(?:\\s+)(?:tags)`, 'g'), $1 => ` ${$1.trim()}`)
//"tags:HUNT tags:HUNT tags:HUNT tags:HUNT"

0

Tập lệnh này xóa bất kỳ khoảng trắng nào (nhiều khoảng trắng, tab, trả về, v.v.) giữa các từ và trims:

// Trims & replaces any wihtespacing to single space between words
String.prototype.clearExtraSpace = function(){
  var _trimLeft  = /^\s+/,
      _trimRight = /\s+$/,
      _multiple  = /\s+/g;

  return this.replace(_trimLeft, '').replace(_trimRight, '').replace(_multiple, ' ');
};

0

'con trỏ chuột chạm' .replace (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") nên thực hiện thủ thuật!


0

Tôi biết chúng ta phải sử dụng regex, nhưng trong một cuộc phỏng vấn, tôi đã được yêu cầu KHÔNG SỬ DỤNG REGEX.

@slightlytyler đã giúp tôi trong cách tiếp cận dưới đây.

const testStr = "I   LOVE    STACKOVERFLOW   LOL";

const removeSpaces = str  => {
  const chars = str.split('');
  const nextChars = chars.reduce(
    (acc, c) => {
      if (c === ' ') {
        const lastChar = acc[acc.length - 1];
        if (lastChar === ' ') {
          return acc;
        }
      }
      return [...acc, c];
    },
    [],
  );
  const nextStr = nextChars.join('');
  return nextStr
};

console.log(removeSpaces(testStr));


xem xét: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes
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.