2011-12-27 4 views
2

Je suis en train de construire une regex pour effectuer les opérations suivantes:regex pour correspondre à mot séparés par des caractères et entouré par des balises xml

Recherchez le mot « alphabet » enfermé dans des balises xml, recherche sélectionnne les éléments suivants:

<hw>Al"pha*bet</hw> 
<hw>Al"pha*be`t</hw>   
<hw>alphabet</hw>  
<hw>al*pha*bet</hw>   
<hw>al"pha"b"et</hw> 

le mot peut être séparé par 3 caractères spéciaux: "*`, la recherche devrait être insensible à la casse, vous pouvez s'il vous plaît me aider en construisant un regex qui recherche spécifiquement pour l'alphabet de mot. ou sans l'un des caractères spéciaux mentionnés ci-dessus

+3

Avez-vous une langue particulière à l'esprit? Notez que ma première pensée serait de tirer les sous-chaînes étiquetées, d'éliminer ces caractères puis de les faire correspondre, mais cela peut ne pas être idéal selon votre langue ou votre jeu de données. –

+0

ouais .. le meilleur moyen de faire ce genre de dépend de quelle langue et comment vous obtenez les données d'exemple pour commencer. Par exemple, si vous utilisez une classe d'analyseur xml (avec par exemple php), vous pouvez facilement saisir les tags avec des fonctions préfabriquées. Mais même s'il s'agissait de racler du contenu brut à l'aide d'une regex pure, il serait encore plus "propre" de supprimer les caractères spéciaux et ensuite de les comparer à "alphabet" ...esp depuis que j'ai une suspicion furtive "alphabet" est juste un mot d'exemple et vous appliquerez ceci à n'importe quel mot ... –

+0

Exemples de chaînes que vous allez correspondre sur, la langue? Que voulez-vous faire correspondre: Le mot, les lignes, les tags (avec le contenu), ou un bloc complet tel que ci-dessus? – Qtax

Répondre

1

Vous pouvez essayer cette

a([`"\*])*l([`"\*])*p([`"\*])*h([`"\*])*a([`"\*])*b([`"\*])*e([`"\*])*t 

Ou cette

>\s*a([`"\*])*l([`"\*])*p([`"\*])*h([`"\*])*a([`"\*])*b([`"\*])*e([`"\*])*t\s*< 

Modifier

Désolé oublièrent pour échapper *

+0

'*' a pas de signification particulière dans une classe de caractère et n'a pas besoin de là échappe et pourquoi utiliser la capture partout des groupes – Qtax

+0

.? @Qtax Je ne suis pas parfait à regex Vous pouvez faire une suggestion – Oybek

+0

@Oybek il signifie que '[\' "\ *]' peut être '[\' "*]' parce que '*' est interprété littéralement à l'intérieur du la classe char (les parenthèses) –

0

Un je suis qui travaille pour les cas que vous avez énumérés:

/<[a-zA-Z]+>al"*\**pha\**\"*b\"*e`*t<\/[a-zA-Z]+>/i 

Découvrez http://www.rubular.com/. Il y a un test en direct des expressions régulières.

+0

Je pense que vous * probablement * étiez trop littéral dans l'interprétation de la question..la position de ces caractères spéciaux est * probablement * juste des exemples et l'un d'eux peut apparaître n'importe où entre les lettres .. –

+0

J'ai aussi une suspicion fautive "alphabet" est juste un mot d'exemple et regex sera appliqué à n'importe quel mot ... Je sais OP n'a pas dit cela, mais juste sayin '... –

+0

D'accord, je vais essayer de corriger ;-) – ThatOtherPerson

2

Cela fonctionne avec la mise en garde que regex ne doit pas être utilisé pour analyser xml/html, etc ..

Il est toujours plus facile de capturer des échantillons simples, puis les sous-processus dans un rappel.
Dans cette capture de cas ([alphabet "*`,] +), bande puis les caractères indésirables, puis faire une comparaison.

Un échantillon Perl, le concept est le même pour Perl/PHP/C#, etc. ..

$sample = ' 
    <hw>Al"pha*bet</hw> 
    <hw>Al"pha*be`t</hw>   
    <hw>alphabet</hw>  
    <hw>al*pha*bet</hw>   
    <hw>al"pha"b"et</hw> 
'; 

$specialword = 'alphabet'; 
$uc_specialword = uc($specialword); 

while ($sample =~ m{<([A-Za-z_:][\w:.-]*)(?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*(?<!/)>([$specialword"*`,]+)</\1\s*>}isg) 
{ 
    ($matchstr, $checkstr) = ($&, $2); 
    $checkstr =~ s/["*`,]//g; 
    if (uc($checkstr) eq $uc_specialword) { 
     print "Found '$checkstr' in '$matchstr'\n"; 
    } 
} 

regex élargi:

m{ # Regex delim 
<       # Open tag 
    ([A-Za-z_:][\w:.-]*)     # Capture 1, the tag name 
    (?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s* # optional attr/val pairs 
    (?<!/) 
> 
([alphabet"*`,]+)  # Capture 2, class of special characters allowed, 'alphabet' plus "*`, 
</\1\s*>     # Close tag, backref to tag name (group 1) 

}xisg # Regex delim. Options: expanded, case insensitive, single line, global 

sortie:

Found 'Alphabet' in '<hw>Al"pha*bet</hw>' 
Found 'Alphabet' in '<hw>Al"pha*be`t</hw>' 
Found 'alphabet' in '<hw>alphabet</hw>' 
Found 'alphabet' in '<hw>al*pha*bet</hw>' 
Found 'alphabet' in '<hw>al"pha"b"et</hw>' 

exemple de PHP

L'utilisation preg_match() se trouvent ici http://www.ideone.com/8EBpx

<?php 

    $sample = ' 
    <hw>Al"pha*bet</hw> 
    <hw>Al"pha*be`t</hw>   
    <hw>alphabet</hw>  
    <hw>al*pha*bet</hw>   
    <hw>al"pha"b"et</hw> 
    '; 

    $specialword = 'alphabet'; 
    $uc_specialword = strtoupper($specialword); 
    $regex = '~<([A-Za-z_:][\w:.-]*)(?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*(?<!/)>([' . $specialword. '"*`,]+)</\1\s*>~xis'; 
    $pos = 0; 

    while (preg_match($regex, $sample, $matches, PREG_OFFSET_CAPTURE, $pos)) 
    { 
    $matchstr = $matches[0][0]; 
    $checkstr = $matches[2][0]; 

    $checkstr = preg_replace('/[" * `,]/', "", $checkstr); 
    if (strtoupper($checkstr) == $uc_specialword) 
     print "Found '$checkstr' in '$matchstr'\n"; 

    $pos = $matches[0][1] + strlen($matchstr); 
    } 

?> 

L'utilisation preg_match_all() peut être trouvée ici http://www.ideone.com/C6HeT

<?php 

    $sample = ' 
    <hw>Al"pha*bet</hw> 
    <hw>Al"pha*be`t</hw>   
    <hw>alphabet</hw>  
    <hw>al*pha*bet</hw>   
    <hw>al"pha"b"et</hw> 
    '; 

    $specialword = 'alphabet'; 
    $uc_specialword = strtoupper($specialword); 
    $regex = '~<([A-Za-z_:][\w:.-]*)(?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*(?<!/)>([' . $specialword. '"*`,]+)</\1\s*>~xis'; 

    preg_match_all($regex, $sample, $matches, PREG_SET_ORDER); 

    foreach ($matches as $match) 
    { 
    $matchstr = $match[0]; 
    $checkstr = $match[2]; 

    $checkstr = preg_replace('/[" * `,]/', "", $checkstr); 
    if (strtoupper($checkstr) == $uc_specialword) 
     print "Found '$checkstr' in '$matchstr'\n"; 
    } 

?> 
+0

$ astring = ~ s/["*' ] // g; $ astring = ~ s/& Verbar; // g; if ($ astring = ~/$ motif/i) quoi ça? où $ pattern est " alphabet"? Existe-t-il un moyen plus simple de traduire cela en C ou en PHP? merci beaucoup pour l'aide! – Alex

+0

@Alex - ajouté quelques exemples PHP. – sln

Questions connexes