Supprimer le terme uniquement s'il est sur sa propre ligne

16

J'ai ceci:

$text = '
   hello world
    
    hello
';

Comment supprimer   uniquement s'il est sur sa propre ligne? Donc, avec l'exemple ci-dessus, le second  doit être supprimé. Les résultats doivent être:

$text = '
   hello world

    hello
';

Ce que j'ai essayé jusqu'à présent

Via str_replace(), je peux:

$text = str_replace(' ', '', $text);

Mais cela supprimera toutes les instances de  , non seulement lorsqu'il est sur sa propre ligne.

Henrik Petterson
la source
6
Belle addition de ce que j'ai essayé jusqu'à présent - devrait être standard sur ce site. +1
Gary Woods
2
@misorude N'hésitez pas à poster une réponse avec votre approche.
Henrik Petterson
1
@OfirBaruch J'ai essayé $text = str_replace('\n'.' '.'\n', '', $text);mais je n'ai pas fonctionné. Tu vois .
Henrik Petterson
3
@FlashThunder Pourquoi ne postez-vous pas une réponse en utilisant str_replace()au lieu de juger mon expérience. =)
Henrik Petterson
2
@misorude Mais c'est quelque chose dont vous devrez discuter avec la communauté sur meta si vous pensez que c'est un problème à l'échelle du site. Pourquoi poussez-vous ici?
Henrik Petterson

Réponses:

10

J'ai déjà essayé cette approche et j'obtiens la sortie souhaitée

// Your initial text
$text = '
   hello world
    
    hello
';

// Explode the text on each new line and get an array with all lines of the text
$lines = explode("\n", $text);

// Iterrate over all the available lines
foreach($lines as $idx => $line) {
    // Here you are free to do any if statement you want, that helps to filter
    // your text.

    // Make sure that the text doesn't have any spaces before or after and 
    // check if the text in the given line is exactly the same is the  
    if ( ' ' === trim($line) ) {
        // If the text in the given line is   then replace this line 
        // with and emty character
        $lines[$idx] = str_replace(' ', '', $lines[$idx]);
    }
}

// Finally implode all the lines in a new text seperated by new lines.
echo implode("\n", $lines);

Ma sortie sur mon local est la suivante:


hello world

 hello
Merianos Nikos
la source
cela supprimera également les espaces blancs, et l'auteur voulait supprimer uniquement 
Flash Thunder
@FlashThunder ce que j'ai en sortie est totalement aligné avec la sortie demandée par la question. Si vous vérifiez que ma sortie est identique à l'exigence initiale :) Avez-vous essayé d'exécuter mon code en PHP 7? Avez-vous obtenu une autre sortie?
Merianos Nikos
Je dirais que l'auteur n'est même pas au courant qu'il y a une tabulation / quelques espaces dedans, car il demandait dans un autre commentaire de l'espace après (et il ne contient pas cela).
Flash Thunder
@FlashThunder Je suis au courant. Je demandais juste un exemple de cas.
Henrik Petterson
1
oh désolé devait être un mauvais coup
Flash Thunder
2

Mon approche serait:

  1. Décomposer le texte sur de nouvelles lignes
  2. Coupez chaque valeur du tableau
  3. Videz chaque élément du tableau avec une valeur  
  4. Imploser avec de nouvelles lignes

Résultat dans le code suivant:

$chunks = explode(PHP_EOL, $text);
$chunks = array_map('trim', $chunks);
foreach (array_keys($chunks, ' ') as $key) {
    $chunks[$key] = '';
}
$text = implode(PHP_EOL, $chunks);
JanP
la source
2
La sortie de votre code n'est pas identique à ce qui est demandé: / `` bonjour & nbsp; monde & nbsp; bonjour '' `` La condition initiale est de remplacer uniquement le  par du texte vide, sans télécommande toute la ligne: /. Aussi, gardez à l'esprit que ce n'est pas moi qui a dévalorisé votre réponse :) Mon commentaire était juste un message amical :)
Merianos Nikos
1
D'accord, j'ai mis à jour ma réponse pour corriger cela
JanP
1
Bien mieux maintenant :)
Merianos Nikos
2

Peut-être quelque chose comme ça:

$text = preg_replace("~(^[\s]?|[\n\r][\s]?)( )([\s]?[\n\r|$])~s","$1$3",$text);

http://sandbox.onlinephpfunctions.com/code/f4192b95e0e41833b09598b6ec1258dca93c7f06

(qui fonctionne sur PHP5 , mais ne fonctionne pas sur certaines versions de PHP7 )


L'alternative serait:

<?php
    $lines = explode("\n",$text);
    foreach($lines as $n => $l)
        if(trim($l) == '&nbsp;')
            $lines[$n] = str_replace('&nbsp;','',$l);
    $text = implode("\n",$lines);
?>
Flash Thunder
la source
1
Je le teste et ne fonctionne pas :). Gardez également à l'esprit que je ne vous ai pas donné de downvotes. C'est juste un commentaire amical :) La sortie reste inchangée après avoir testé votre solution.
Merianos Nikos
@MerianosNikos comment n'est-ce pas ?? sandbox.onlinephpfunctions.com/code/…
Flash Thunder
1
Voilà ce que je reçois dans mon local lorsque je lance votre code: pasteboard.co/IUkf2MK.png :)
Merianos Nikos
2
@MerianosNikos oh drôle, fonctionne sur PHP5 mais ne fonctionne pas sur PHP7.
Flash Thunder
Peut-être que tu as raison. Je l'exécute sur php 7.
Merianos Nikos
1

Si vous connaissez vos caractères de fin de ligne et que votre &nbsp;est toujours suivi d'une nouvelle ligne:

<?php
$text = '
   hello&nbsp;world
   &nbsp;
   &nbsp;hello
';


print str_replace("&nbsp;\n", "\n", $text);

Sortie (certains espaces blancs perdus dans le formatage ici):

   hello&nbsp;world

   &nbsp;hello

Avertissement: toute ligne se terminant par un avec un &nbsp;autre contenu précédent serait également affectée, ce qui pourrait ne pas répondre à vos besoins.

Progrock
la source
1
C'est en fait une solution très solide si nous nous en tenons à str_replace()!
Henrik Petterson
est-ce? Je peux voir plus de cas où cela ne fonctionnerait pas
Flash Thunder
@Progrock est-il possible de l'ajuster de manière à ce qu'il tienne compte des espaces après &nbsp;? Par exemple:"&nbsp; \n"
Henrik Petterson
@HenrikPetterson no
Flash Thunder
1

Vous pouvez utiliser une expression régulière pour cela, en utilisant les modificateurs DOTALL et MULTILINE avec des assertions de regard:

preg_replace("~(?sm)(?<=\n)\s*&nbsp;(?=\n)~", '',$text);
  • (?sm): DOTALL (s) MULTILINE (m)
  • (?<=\n): saut de ligne précédent (ne fait pas partie du match)
  • \s*&nbsp;\s*: simple & nbsp; avec espace blanc environnant en option
  • (?=\n): retour à la ligne (ne fait pas partie du match)
>>> $text = '                                                                                               
 hello&nbsp;world                                                                                         
 &nbsp;                                                                                                   
 &nbsp;hello                                                                                           
 ';
=> """
   \n
      hello&nbsp;world\n
      &nbsp;\n
      &nbsp;hello\n
   """
>>> preg_replace("~(?sm)(?<=\n)\s*&nbsp;\s*(?=\n)~", '',$text);
=> """
   \n
      hello&nbsp;world\n
   \n
      &nbsp;hello\n
   """
>>>
Tom Regner
la source
0

Vous pouvez diviser en lignes, puis remplacer &nbsp;la chaîne vide sur les lignes qui contiennent uniquement un &nbsp;et un espace.

Nous conserverons les fins de ligne d'origine, en les capturant.

<?php

$text = '
   hello&nbsp;world
   &nbsp;
   &nbsp;hello
';
$lines = preg_split('@(\R)@', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach($lines as &$v)
    if (trim($v) === '&nbsp;')
        $v = str_replace('&nbsp;', '', $v);

$result = implode($lines);
var_dump($result);

Production:

string(40) "
   hello&nbsp;world

   &nbsp;hello
"
Progrock
la source