2010-03-25 2 views
1

Prenons par exemple la correspondance regex suivante.preg_match pour faire correspondre une chaîne optionnelle, mais ne correspond pas à la totalité de la chaîne

preg_match('!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(/page-[0-9]+)?$!', 'publisher/news/1/2010-march:03-23/test_title/1/page-1', $matches); 
print_r($matches); 

Il produit les éléments suivants:

Array 
(
    [0] => publisher/news/1/2010-march:03-23/test_title/1/page-1 
    [1] => news 
    [2] => 1 
    [3] => 2010 
    [4] => march 
    [5] => 03 
    [6] => 23 
    [7] => test_title 
    [8] => 1 
    [9] => /page-1 
) 

Cependant, comme le dernier match est en option, il peut également fonctionner avec les éléments suivants correspondant à « éditeur/nouvelles/1/2010-mars: 03-23 ​​/ test_title /1". Mon problème est que je veux être capable de faire correspondre (/ page- [0-9] +) si elle existe, mais ne correspond qu'au numéro de page de sorte que "publisher/news/1/2010-mars: 03-23 ​​/ test_title/1/Page-1" correspond comme ceci:

Array 
(
    [0] => publisher/news/1/2010-march:03-23/test_title/1/page-1 
    [1] => news 
    [2] => 1 
    [3] => 2010 
    [4] => march 
    [5] => 03 
    [6] => 23 
    [7] => test_title 
    [8] => 1 
    [9] => 1 
) 

J'ai essayé le regex suivant

'!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)/?p?a?g?e?-?([0-9]+)?$!' 

Cela fonctionne, mais il correspondra aussi « éditeur/nouvelles/1/2010-mars : 03-23 ​​/ test_title/1/1 ". Je n'ai aucune idée d'effectuer un match mais de ne pas le faire revenir dans les matchs? Est-ce possible dans une seule regex?

Répondre

2

absolument pas correspondre publisher/news/1/2010-march:03-23/test_title/1/whatever

!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(?:/page-([0-9]+))?$! 

Pour correspondre encore publisher/news/1/2010-march:03-23/test_title/1/whatever mais ignorer la /whatever:

!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(?:(?:/page-([0-9]+))|/.*)?$! 
+0

C'est le ticket. Merci. Est-ce que?: Signifie match seulement s'il existe? – buggedcom

+0

?: Rend les parenthèses "non-capturantes". Ainsi, dans le tableau de votre exemple, 0 correspond à la chaîne entière correspondant à votre modèle. 1-9 sont des "captures", tout ce que vous avez enveloppé() dans votre modèle. (?:) regroupe la "/ page" et la "[0-9] +" ensemble, mais ne les "capture" pas. –

+0

Ah k à la vôtre. Désolé je ne peux pas voter, je n'ai pas encore mon représentant +15 – buggedcom

0

peut-être comme ça:

'!^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)(/page-([0-9]+))?$!' 
+0

Non car cela correspondrait alors à "/ page-1" et "1". Je veux seulement qu'il corresponde au "1". Il est utilisé un système de routage d'URL automatisé et les correspondances regex sont remplacées dans des espaces réservés, de sorte que toutes les correspondances renvoyées doivent correspondre au nombre d'espaces réservés. – buggedcom

0

C'est le regex ce que vous êtes recherche pour:

^publisher/([A-Za-z0-9\-\_]+)/([0-9]+)/([0-9]{4})-(january|february|march|april|may|june|july|august|september|october|november|december):([0-9]{1,2})-([0-9]{1,2})/([A-Za-z0-9\-\_]+)/([0-9]+)/(?:page-(\d+))? 

Vous pouvez le tester dans rexexbuddy. Si "page-1" n'est pas positionné, la var 9 restera vide sinon elle le règlera.

+0

Merci, mais Matt vous a aussi battu la réponse. Y a-t-il vraiment un avantage de (\ d +) sur ([0-9] +)? – buggedcom

+0

Je ne suis pas sûr s'il y a vraiment une différence de performance. \ d est destiné aux chiffres alors que [0-9] est juste une plage comme vous pouvez utiliser [a-z] aussi. – RJD22

Questions connexes