2010-09-14 7 views
0

Je rencontre des problèmes pour créer la regex correcte pour ma chaîne. Ce que je veux faire, c'est obtenir toutes les entités de ma chaîne; ils commencent et se terminent par '. Les entités sont identifiables par un nombre de chiffres et un # à l'avant. Cependant, les entités (dans ce cas, un numéro de téléphone commençant par #) qui ne commencent pas ou ne se terminent pas par ' ne doivent pas être appariées du tout.RegEx a RegEx match

J'espère que quelqu'un peut m'aider, ou au moins me dire que ce que je veux faire n'est pas possible dans une regex.Merci :)

cordes:

'Blaa lablalbl balbla balb lbal '#39'blaaaaaaaa'#39' ('#39#226#8218#172#39') blaaaaaaaa #7478347878347834 blaaaa blaaaa'

RegEx:

'[#[0-9]+]*'

Recherché matches:

  • '#39'
  • '#39'
  • '#39'
  • '#226'
  • '#8218'
  • '#172'
  • '#39'

Résultats trouvés:

  • '#39'
  • '#39'
  • '#39#226#8218#172#39' < - doit être divisé (si possible dans le même RegEx)

Une autre RegEx:

#[0-9]+

Résultats trouvés:

  • '#39'
  • '#39'
  • '#39'
  • '#226'
  • '#8218'
  • '#172'
  • '#39'
  • '#7478347878347834' < - ne devrait être ici :(

Langue: C# .NET (4.0)

+1

Quelle langue regexp? – gnarf

+0

@ ApoY2k Parce que ce n'est pas * directement * entouré par le caractère "", je suppose. Peut-être (probablement?) Tort, cependant. – jensgram

+0

# 7478347878347834 n'est pas autorisé car il fait partie de la chaîne et n'est donc pas une entité. – Willy

Répondre

1

En supposant que vous pouvez utiliser/lookaheads et arrières, que votre regexp prend en charge de longueur variable d'assertions arrières (JGsoft/.NET uniquement)

(?<='[#0-9]*)#\d+(?=[#0-9]*') 

devrait fonctionner ... testiez using this site et a obtenu ces résultats:

1. #39 
    2. #39 
    3. #39 
    4. #226 
    5. #8218 
    6. #172 
    7. #39 

Décomposant est assez simple:

(?<=  # Start positive lookbehind group - assure that the text before the cursor 
      # matches the following pattern: 
    '   # Match the literal ' 
    [#0-9]* # Matches #, 0-9, zero or more times 
)   # End lookbehind... 
#\d+  # Match literal #, followed by one or more digits 
(?=   # Start lookahead -- Ensures text after cursor matches (without advancing) 
    [#0-9]* # Allow #, 0-9, zero or more times 
    '   # Match a literal ' 
) 

Ainsi, ce modèle correspondra #\d+ si le texte avant qu'il ne soit '[#0-9]* et le texte après est-[#0-9]*'

+0

Wow, ça marche parfaitement! Exactement ce que je cherchais. Pourriez-vous expliquer ce que cela fait exactement? Merci beaucoup :) – Willy

+0

Vous monsieur, sont KING! – Willy

+0

@Willy - Honnêtement si - J'ai voté pour la réponse @ Jan. Il est plus facile de comprendre ce que vous faites là ... – gnarf

3

Vous ne pouvez pas le faire dans un regex, vous aurez besoin de deux:

d'abord prendre tous les matches qui sont entre guillemets simples:

'[\d#]+' 

ensuite sur tous les matchs, faites ceci:

#\d+ 

vous finirez avec quelque chose comme (en C#):

foreach(var m in Regex.Matches(inputString, @"'[\d#]+'")) 
{ 
    foreach(var m2 in Regex.Matches(m.Value, @"#\d+")) 
    { 
      yield return m2.Value; 
    } 
} 
+0

Dommage que ce ne soit pas possible dans un RegEx, devinez cela devra faire. Merci de l'avoir tapé pour moi aussi;) – Willy

+0

Gnarf posté une réponse qui le fait dans un RegEx, merci! – Willy

1

Comme vous ne spécifiez pas une langue, voici une solution en Perl:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 

my $s = qq!Blaa lablalbl balbla balb lbal '#39'blaaaaaaaa'#39' ('#39#226#8218#172#39') blaaaaaaaa #7478347878347834 blaaaa blaaaa!; 

my @n = $s =~ /(?<=['#\d])(#\d+)(?=[#'\d])/g; 

print Dumper(\@n); 

sortie :

$VAR1 = [ 
      '#39', 
      '#39', 
      '#39', 
      '#226', 
      '#8218', 
      '#172', 
      '#39' 
     ]; 
+0

Je n'avais aucune idée que RegEx était spécifique à la langue , le bit RegEx fonctionne universellement bien? Cela fait aussi l'affaire, # \ d + (? = # | '). Merci! Votre RegEx est beaucoup plus court que celui publié par Gnarf, quelles sont les différences? – Willy

+0

Ses seuls tests que le caractère suivant le match est un '#' ou '' '- et pas toutes les expressions régulières peuvent gérer lookahead, lookbehind, etc. Si vous mettez un' # 'après' # # 7478347878347834' dans votre chaîne de test – gnarf

+0

Testé, vous avez raison :) – Willy