2010-10-21 20 views
1

J'essaie d'écrire une expression régulière qui remplace les sauts de ligne entre certaines zones d'un fichier texte, mais uniquement en mode plain. contenu textuel (c'est-à-dire exclut le texte à l'intérieur du contenu de l'attribut HTML, comme href) mais n'a pas beaucoup de chance après la première partie.Expression régulière pour remplacer les sauts de ligne avec un espace uniquement si la rupture ne figure pas dans le contenu d'un attribut HTML

entrée Exemple:

AUTHOR: Me 
DATE: Now 
CONTENT: 
This is an example. This is another example. <a href="http://www.stackoverflow/example- 
link-that-breaks">This is an example.</a> This is an example. This is yet another 
example. 
END CONTENT 
COMMENTS: 0 

sortie Exemple:

AUTHOR: Me 
DATE: Now 
CONTENT: 
This is an example. This is another example. <a href="http://www.stackoverflow/example-link-that-breaks">This is an example.</a> This is an example. This is yet another example. 
END CONTENT 
COMMENTS: 0 

Donc, idéalement, un espace remplace les sauts de ligne si elles se produisent dans le texte brut, mais les enlève sans ajouter d'espace si elles sont à l'intérieur Paramètres HTML (principalement href, et je vais bien si je dois le limiter).

+0

Quelle langue/outil utilisez-vous? Par exemple, Perl, PHP, Java, Notepad ++ ...? –

+0

Je vais utiliser n'importe quoi, j'ai une configuration XAMPP donc PHP est bien, ou je peux installer Notepad ++. Les fichiers sont assez volumineux (25mb-150mb) si c'est une considération. –

+0

Ne vous embêtez pas avec Notepad ++; sa saveur regex (héritée de SciTE) est terriblement limitée. Je l'ai jeté dans le pire des cas. ;) PHP ira bien. –

Répondre

1

Cela permettra d'éliminer les nouvelles lignes dans les valeurs d'attributs, en supposant que les valeurs sont enfermées dans des guillemets doubles:

$s = preg_replace(
     '/[\r\n]+(?=[^<>"]*+"(?:[^<>"]*+"[^"<>]*+")*+[^<>"]*+>)/', 
     '', $s); 

Le préanalyse affirme que, entre la position actuelle (où la nouvelle ligne a été trouvé) et la prochaine >, il y a un nombre impair de doubles quotes. Cela n'autorise pas les valeurs entre guillemets simples ou les chevrons entre les valeurs; les deux peuvent être accommodés si besoin est, mais c'est déjà assez laid. ;)

Après cela, vous pouvez remplacer les nouvelles lignes restantes avec des espaces:

$s = preg_replace('/[\r\n]+/', ' ', $s); 

See it in action on ideone.com.

+0

Cela fonctionne très bien jusqu'ici avec mes fichiers de test, le seul problème est qu'il supprime toutes les nouvelles lignes au lieu de celles entre "CONTENT" et "END CONTENT". Est-il préférable de traiter manuellement cette limite en PHP ou de le construire dans l'expression rationnelle? –

+0

Je le ferais séparément. Cette regex est déjà assez compliquée. –

+0

D'accord, cette regex est géniale. Merci beaucoup Alan! –

1

Idéalement, vous utiliseriez un analyseur HTML réel (ou XML il était XHTML) et remplacer le contenu de l'attribut avec cela.

Cependant, ce qui suit peut faire l'affaire si le moteur supporte lookbehind positif de longueur arbitraire:

(?<=\<[^<>]+=\s*("[^"]*|'[^']*))[\r\n]+ 

Utilisation: Remplacer toutes les occurences de ce regex avec une chaîne vide.

+0

Merci, je vais essayer. Aviez-vous un moteur particulier en tête? –

+0

Le moteur .NET fonctionne bien pour cela, pas Java (du moins pas la dernière fois que j'ai essayé), pas sûr de PCRE et d'autres. Essayez-le - si cela ne fonctionne pas, vous pouvez toujours convertir l'expression en une seule et juste ajuster les caractères cr/nl à la fin du match et utiliser cela comme remplacement, utilisez quelque chose comme '(\ <[^<>] + = \ s * (?: "[^"] * | '[^'] *)) [\ r \ n] + 'comme motif et' $ 1' (ou tout ce que le moteur utilise pour référencer un groupe de capture) comme motif de remplacement. – Lucero

+0

Les seules saveurs qui prennent en charge le lookbehind illimité sont .NET et JGSoft (EditPad Pro, PowerGrep). Mais vous pouvez utiliser un lookahead à la place; vois ma réponse. –