2009-04-02 29 views
27

Tôi cần xóa các dòng trống (có khoảng trống hoặc hoàn toàn trống) trong PHP. Tôi sử dụng biểu thức chính quy này, nhưng nó không hoạt động:Làm cách nào để xóa các dòng trống khỏi văn bản trong PHP?

$str = ereg_replace('^[ \t]*$\r?\n', '', $str); 
$str = preg_replace('^[ \t]*$\r?\n', '', $str); 

tôi muốn kết quả của:

blahblah 

blahblah 

    adsa 


sad asdasd 

sẽ:

blahblah 
blahblah 
    adsa 
sad asdasd 

Trả lời

62
// New line is required to split non-blank lines 
preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string); 

Các biểu hiện thường xuyên trên nói:

/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/ 
    1st Capturing group (^[\r\n]*|[\r\n]+) 
     1st Alternative: ^[\r\n]* 
     ^assert position at start of the string 
      [\r\n]* match a single character present in the list below 
       Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy] 
       \r matches a carriage return (ASCII 13) 
       \n matches a fine-feed (newline) character (ASCII 10) 
     2nd Alternative: [\r\n]+ 
      [\r\n]+ match a single character present in the list below 
      Quantifier: Between one and unlimited times, as many times as possible, giving back as needed [greedy] 
      \r matches a carriage return (ASCII 13) 
      \n matches a fine-feed (newline) character (ASCII 10) 
    [\s\t]* match a single character present in the list below 
     Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy] 
     \s match any white space character [\r\n\t\f ] 
     \tTab (ASCII 9) 
    [\r\n]+ match a single character present in the list below 
     Quantifier: Between one and unlimited times, as many times as possible, giving back as needed [greedy] 
     \r matches a carriage return (ASCII 13) 
     \n matches a fine-feed (newline) character (ASCII 10) 
+0

này cũng được tìm thấy ở đây: http://programming-oneliners.blogspot.com/2006/03/remove-blank-empty-lines-php-29.html – Jamie

+5

trở preg_replace ("/ (^ [ \ r \ n] * | [\ r \ n] +) [\ s \ t] * [\ r \ n] +/"," \ n ", $ string); công việc này – StoneHeart

+0

Bạn có thể giải thích chính xác những gì regex không? Tôi không thích sử dụng mã mà tôi không biết gì cả. – Achshar

1

gì về điều này?

$str = preg_replace('^\s+\r?\n$', '', $str); 
20

giải pháp ereg-replace() của bạn là sai vì ereg/eregi phương pháp không được tán thành. preg_replace() của bạn thậm chí sẽ không biên dịch, nhưng nếu bạn thêm delimiters và thiết lập chế độ multiline, nó sẽ hoạt động tốt:

$str = preg_replace('/^[ \t]*[\r\n]+/m', '', $str); 

Các modifier m phép ^ để phù hợp với sự bắt đầu của một dòng logic chứ không phải chỉ là khởi đầu của toàn bộ chuỗi. Neo bắt đầu của dòng là cần thiết bởi vì không có nó regex sẽ phù hợp với dòng mới ở cuối mỗi dòng, không chỉ là những cái trống. Bạn không cần neo cuối dòng ($) vì bạn đang tích cực khớp với các ký tự dòng mới, nhưng nó không bị tổn thương.

accepted answer hoàn thành công việc, nhưng nó phức tạp hơn mức cần thiết. Regex phải khớp với phần đầu của chuỗi (^[\r\n]*, chế độ đa dòng không được đặt) hoặc ít nhất một dòng mới ([\r\n]+), theo sau là ít nhất một dòng mới ([\r\n]+). Vì vậy, trong trường hợp đặc biệt của chuỗi bắt đầu bằng một hoặc nhiều dòng trống, chúng sẽ được thay thế bằng một dòng trống. Tôi khá chắc chắn đó không phải là kết quả mong muốn.

Nhưng phần lớn thời gian là thay thế hai hoặc nhiều dòng mới liên tiếp, cùng với bất kỳ dấu cách ngang nào (dấu cách hoặc tab) nằm giữa chúng, với một dòng cấp. Đó là ý định, dù sao đi nữa. Tác giả dường như mong đợi \s để chỉ khớp với ký tự khoảng trắng (\x20), khi thực tế nó khớp với bất kỳ ký tự khoảng trống nào. Đó là một sai lầm rất phổ biến. Danh sách thực tế thay đổi từ một hương vị regex sang vị trí tiếp theo, nhưng tối thiểu bạn có thể mong đợi \s để khớp với bất kỳ kết quả nào phù hợp với [ \t\f\r\n].

Trên thực tế, trong PHP bạn có một lựa chọn tốt hơn:

$str = preg_replace('/^\h*\v+/m', '', $str); 

\h phù hợp với bất kỳ ký tự khoảng trắng ngang, và \v trận dọc khoảng trắng.

+0

'\ h' yêu cầu động cơ pcre là phiên bản tối thiểu hoặc là một cơn ác mộng của kết quả. Chỉ cần một đầu lên. – Anthony

0
function trimblanklines($str) { 
    return preg_replace('`\A[ \t]*\r?\n|\r?\n[ \t]*\Z`','',$str); 
} 

Điều này chỉ xóa chúng ngay từ đầu và cuối chứ không phải giữa (nếu có ai khác đang tìm kiếm).

+1

Chúng ta không nên sử dụng 'trim ($ str); 'Nó thực hiện thủ thuật cho câu trả lời của bạn! – bantya

+1

@bantya Điều đó hoàn toàn không giống nhau.Hàm của tôi loại bỏ hàng đầu và cuối hoàn toàn trống/khoảng trắng * dòng *, giống như từ một đoạn văn bản. Nếu dòng đầu tiên trống và dòng thứ hai được thụt lề, các khoảng trống đó sẽ không được chạm vào ngay cả khi chúng ở đầu. – mpen

5

Các comment from Bythos từ liên kết của Jamie trên làm việc cho tôi:

/^\n+|^[\t\s]*\n+/m 

Tôi không muốn tước tất cả các dòng mới, chỉ là trống/những khoảng trắng. Điều này làm các trick!

1

Hãy thử điều này một:

$str =preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\r\n", $str); 

Nếu bạn xuất này vào một tập tin văn bản, Nó sẽ cho cùng một sản lượng trên notepad đơn giản, Wordpad và cũng trên soạn thảo văn bản như Notepad ++.

+1

Đây là 99,9% câu trả lời giống như câu trả lời đã chọn. Có lẽ bạn có thể thử một cái gì đó độc đáo mà thực sự sẽ đóng góp cho câu hỏi ban đầu. Bạn không giải thích regex làm gì! – GTodorov

0

Câu trả lời được chấp nhận để lại dấu ngắt dòng bổ sung ở cuối chuỗi. Sử dụng rtrim() sẽ loại bỏ linebreak thức này:

rtrim(preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string)); 
8

Chỉ cần nổ theo dòng của văn bản để một mảng, loại bỏ dòng trống sử dụng array_filter và nổ tung mảng một lần nữa.

$tmp = explode("\n", $str); 
$tmp = array_filter($tmp); 
$str = implode("\n", $tmp); 

Hoặc trong một dòng:

$str = implode("\n", array_filter(explode("\n", $str))); 

Tôi không biết, nhưng điều này là có thể nhanh hơn preg_replace.

+1

Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và/hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó. – JAL

+0

Bạn nói đúng. Cảm ơn. – Ben

+0

Ben, điều này sẽ không hoạt động vì bạn phát "n" số "\ n" và sau đó những gì bạn làm là thêm cùng một số "\ n" và xây dựng lại cùng một chuỗi. – GTodorov

0

Từ this answer, hoạt động tốt cho tôi!

$str = "<html> 
<body>"; 

echo str_replace(array("\r", "\n"), '', $str); 
Các vấn đề liên quan