2010-03-21 2 views
1

J'ai une liste de test que j'essaye de capturer des données d'utiliser une regex.Regex pour capturer la liste de texte numérotée

Voici un échantillon du format texte:

(1) this is a sample string /(2) something strange /(3) another bit of text /(4) the last one/ something!/ 

J'ai un Regex qui capte actuellement correctement, mais je rencontre quelques difficultés à le faire fonctionner dans des conditions aberrantes.

Voici mon regex

/\(?\d\d?\)([^\)]+)(\/|\z)/ 

Malheureusement certaines des données contient des parenthèses comme ceci:

(1) this is a sample string (1998-1999) /(2) something strange (blah) /(3) another bit of text /(4) the last one/ something!/ 

Les sous-chaînes '(1998-1999)' et '(bla)' faire échouer !

Quelqu'un veut-il avoir une fissure à celui-ci? Merci: D

+0

vous ne dites pas exactement ce que l'expression rationnelle est censé capturer. – user187291

+0

Désolé de ne pas être plus précis. Je passe en revue la ruée des réponses maintenant (au moins 2 regarde bien) * sourire * J'essayais de capturer le texte que mon exemple capture (c'est-à-dire le texte anglais moins la numérotation). – pchap10k

Répondre

1

Je voudrais essayer ceci:

\((\d+)\)\s+(.*?)(?=/(?:\(\d+\)|\z)) 

Cette regex recherche plutôt effrayant fait ce qui suit:

  • Il recherche un ou plusieurs chiffres enveloppées entre parenthèses et les capture;
  • Il doit y avoir au moins un caractère espace blanc après les chiffres entre parenthèses. Cet espace blanc est ignoré (non capturé);
  • Une expression générique non gourmande est utilisée. C'est (imho) le moyen préférable d'utiliser des groupes de caractères négatifs (par exemple [^/]+) pour ce type de problème;
  • Le positif préanalyse ((?=...)) dit l'expression doit être suivie d'une barre oblique inverse, puis l'un des:
    • un ou plusieurs chiffres enveloppées entre parenthèses; ou
    • le terminateur de chaîne.

Pour vous donner un exemple en PHP (vous ne spécifiez pas votre langue):

$s = '(1) this is a sample string (1998-1999) /(2) something strange (blah) /(3) another bit of text /(4) the last one/ something!/'; 
preg_match_all('!\((\d+)\)\s+(.*?)(?=/(?:\(\d+\)|\z))!', $s, $matches); 
print_r($matches); 

sortie:

Array 
(
    [0] => Array 
     (
      [0] => (1) this is a sample string (1998-1999) 
      [1] => (2) something strange (blah) 
      [2] => (3) another bit of text 
      [3] => (4) the last one/ something! 
     ) 

    [1] => Array 
     (
      [0] => 1 
      [1] => 2 
      [2] => 3 
      [3] => 4 
     ) 

    [2] => Array 
     (
      [0] => this is a sample string (1998-1999) 
      [1] => something strange (blah) 
      [2] => another bit of text 
      [3] => the last one/ something! 
     ) 

) 

Quelques notes:

  • Vous ne spécifiez pas ce que vous voulez capturer ure. J'ai supposé le numéro d'article de la liste et le texte. Cela pourrait être faux, auquel cas il suffit de laisser tomber ces parenthèses de capture. De toute façon, vous pouvez obtenir le match entier;
  • J'ai supprimé le slash final de la correspondance. Ce n'est peut-être pas votre intention. Encore une fois juste changer la capture en fonction;
  • J'ai autorisé n'importe quel nombre de chiffres pour le numéro d'article. Votre version a permis seulement deux. Si vous le préférez, remplacez \d+ par \d\d?.
+0

C'était certainement la Rolls Royce des réponses. Il capture tout bien dans Ruby aussi. Formaté pour Ruby J'utilise ceci ... /\(\d+\).*?\/(?=\(|$)/ – pchap10k

+0

Cletus: Je viens de remarquer que la barre oblique incorporée dans la dernière entrée est en cours d'écrêtage. Je vous ai déjà voté, et je suis en train de déchiffrer la regex maintenant, mais pouvez-vous suggérer comment inclure du texte après une barre oblique? Thx – pchap10k

+0

@crunchyt pouvez-vous expliquer? Le '/' final, le voulez-vous dans le deuxième groupe capturé? Ou voulez-vous dire quelque chose d'autre? – cletus

1

Prepend un / au début de la chaîne, ajoutez un (0) à la fin de la chaîne, puis diviser l'ensemble de la chaîne avec le motif \/\(\d+\), et jeter les premier et dernier éléments vides.

1

Tant que/ne peut apparaître dans le texte ...

\(?\d?\d[^/]+ 
+0

C'était proche, mais j'ai besoin de toute la chaîne entre les chiffres. – pchap10k

Questions connexes