web-dev-qa-db-fra.com

Comment puis-je supprimer les lignes vides du texte en PHP?

J'ai besoin de supprimer les lignes vides (avec des espaces ou absolument blanches) en PHP J'utilise cette expression régulière, mais ça ne marche pas:

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

je veux le résultat de:

blahblah

blahblah

   adsa 


sad asdasd

volonté:

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

L'expression régulière ci-dessus dit:

/(^[\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)
71
Michael Wales

Votre solution ereg-replace() est incorrecte car les méthodes ereg/eregi sont obsolètes. Votre preg_replace() ne sera même pas compilé, mais si vous ajoutez des délimiteurs et définissez le mode multiligne, cela fonctionnera correctement:

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

Le modificateur m permet à ^ de faire correspondre le début d'une ligne logique plutôt que le début de la chaîne entière. L'ancre de début de ligne est nécessaire car, sans elle, l'expression régulière correspondrait à la nouvelle ligne à la fin de chaque ligne, pas seulement à celles qui sont vides. Vous n'avez pas besoin de l'ancre de fin de ligne ($) car vous faites correspondre activement les caractères de nouvelle ligne, mais cela ne fait pas de mal.

La réponse acceptée fait le travail, mais c'est plus compliqué que nécessaire. L'expression rationnelle doit correspondre au début de la chaîne (^[\r\n]*, le mode multiligne non défini) ou à au moins une nouvelle ligne ([\r\n]+), suivie d'au moins une nouvelle ligne ([\r\n]+). Ainsi, dans le cas particulier d'une chaîne commençant par une ou plusieurs lignes vides, elles seront remplacées par une ligne vierge. Je suis presque sûr que ce n'est pas le résultat souhaité.

Mais ce qu’il fait la plupart du temps est de remplacer deux nouvelles lignes consécutives ou plus, ainsi que tout espace horizontal (espaces ou tabulations) qui les sépare, avec un seul saut de ligne. C'est l'intention, de toute façon. L’auteur semble s’attendre à ce que \s corresponde uniquement au caractère espace (\x20), alors qu’il correspond à n’importe quel caractère blanc. C'est une erreur très commune. La liste actuelle varie d’un type d’expression regex à l’autre, mais vous pouvez au moins vous attendre à ce que \s corresponde à ce que [ \t\f\r\n] correspond.

En fait, dans PHP vous avez une meilleure option:

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

\h correspond à n’importe quel caractère d’espace horizontal et \v correspond à un espace vertical.

23
Alan Moore

Il suffit d'exploser les lignes du texte dans un tableau, de supprimer les lignes vides à l'aide de array_filter et d'imploser à nouveau le tableau.

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

Ou en une ligne:

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

Je ne sais pas, mais c'est peut-être plus rapide que preg_replace.

10
Ben

Le commentaire de Bythos du lien de Jamie ci-dessus a fonctionné pour moi:

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

Je ne voulais pas effacer toutes les nouvelles lignes, juste celles vides/espaces blancs. Cela fait l'affaire!

6
Dan Power

Essaye celui-là:

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

Si vous exportez ceci dans un fichier texte, cela produira le même résultat sur un simple bloc-notes, Wordpad ainsi que sur des éditeurs de texte, par exemple Notepad ++.

1
Nauman Tahir

et ça?

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

La réponse acceptée laisse un saut de ligne supplémentaire à la fin de la chaîne. Utiliser rtrim() supprimera ce saut de ligne final:

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

Il n'y a pas besoin de trop compliquer les choses, cela peut être réalisé avec une simple expression rationnelle courte:

$text = preg_replace("/(\R){2,}/", "$1", $text);

Le (\R) correspond à toutes les nouvelles lignes
Le {2,} correspond à deux occurrences ou plus
Le $1 utilise la première backreference (EOL spécifique à la plate-forme) comme substitut

0
Paul

De cette réponse , marche bien pour moi!

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

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

Celui-ci ne les supprime qu'au début et à la fin, pas le milieu (si quelqu'un d'autre le recherchait).

0
mpen