web-dev-qa-db-fra.com

regex correspond à n'importe quel espace

Je veux faire un remplacement en utilisant la fonction regex et preg_replace. c'est mon code

$verif = "/wordA(\s*)wordB(?! wordc)/i";
$replacement = 'wordA wordb wordc';
$newvar = preg_replace($verif, $replacement, $article->text);

Cela fonctionne si seulement nous avons un espace entre wordA et wordB. J'ai besoin de faire correspondre le nombre d'espaces entre wordA et wordB.

exemple:

wordA (10 espaces blancs ou plus) wordB -> motA wordb wordc même motA (1 espace blanc) wordB -> wordA wordb wordc ...

14
user3344311

Votre regex devrait fonctionner "tel quel". En supposant qu'il fait ce que vous voulez.

wordA(\s*)wordB(?! wordc)

Cela signifie que correspond à wordA suivi de 0 espace ou plus suivi de wordB, mais ne correspond pas s'il est suivi de wordc. Notez l'espace unique entre ?! et wordc ce qui signifie que wordA wordB wordc ne correspondra pas, mais wordA wordB wordc volonté.

Voici quelques exemples de correspondances et la sortie de remplacement associée:

enter image description here

Notez que toutes les correspondances sont remplacées quel que soit le nombre d'espaces. Il y a quelques autres points: -

  • (?! wordc) est une anticipation négative, donc vous ne correspondrez pas aux lignes wordA wordB wordc qui est supposé être destiné (et c'est pourquoi la dernière ligne ne correspond pas). Actuellement, vous comptez sur l'espace après ?! pour correspondre à l'espace blanc. Vous voudrez peut-être être plus précis et utiliser (?!\swordc). Si vous souhaitez faire correspondre plusieurs espaces avant wordc, vous pouvez utiliser (?!\s*wordc) pour 0 espace ou plus ou (?!\s*+wordc) pour 1 ou plusieurs espaces selon votre intention. Bien sûr, si vous voulez faire correspondre les lignes avec wordc après wordB, vous ne devez pas utiliser d'anticipation négative.

  • * correspondra à 0 ou plusieurs espaces, il correspondra donc à wordAwordB. Vous voudrez peut-être envisager + si vous voulez au moins un espace.

  • (\s*) - les crochets indiquent un groupe de capture. Capturez-vous l'espace blanc à un groupe pour une raison? Sinon, vous pouvez simplement supprimer les crochets, c'est-à-dire utiliser simplement \s.

Mise à jour basée sur un commentaire

Bonjour, le problème n'est pas l'expression mais les sorties HTML qui ne sont pas considérées comme des espaces. c'est un site web Joomla.

En préservant votre expression originale, vous pouvez utiliser:

wordA((?:\s| )*)wordB(?!(?:\s| )wordc)

La seule différence est que les expressions rationnelles ne correspondent pas aux espaces blancs OR  . J'ai remplacé wordc par \swordc puisque c'est plus explicite. Notez que j'ai déjà souligné que l'anticipation négative ?! ne correspondra pas lorsque wordB est suivi d'un seul espace et wordc. Si vous souhaitez faire correspondre plusieurs espaces blancs, consultez mes commentaires ci-dessus. J'ai également conservé le groupe de capture autour de l'espace, si vous ne le souhaitez pas, supprimez les crochets comme déjà décrit ci-dessus.

Exemples de correspondances:

enter image description here

13
acarlon

La raison pour laquelle j'ai utilisé un + au lieu d'un '*' est dû au fait qu'un plus est défini comme un ou plusieurs des éléments précédents, où un astérisque vaut zéro ou plus. Dans ce cas, nous voulons un délimiteur un peu plus concret, donc "un ou plusieurs" espaces.

Word[Aa]\s+Word[Bb]\s+Word[Cc]

correspondra:

wordA wordB     wordC
worda wordb wordc
wordA   wordb   wordC

Les mots, dans cette expression, devront être spécifiques, et aussi dans l'ordre (a, b, puis c)

1
mrres1