Le placement de marqueurs de texte à l'intérieur de chaînes est-il de mauvais style? Y a-t-il une alternative?

10

Je travaille avec des cordes massives qui nécessitent beaucoup de manipulation.

Par exemple, je pourrais générer une chaîne comme celle-ci:

Partie 1
Bateau

Section A
Programmation

Partie 2
Partitionnement des bateaux pour la programmation.

Section AA
Section SQL Entrées.

La chaîne serait trop grande pour en vérifier manuellement chaque partie. Maintenant, j'ai besoin de splitcela stringen stringlistsections et en parties. Je peux penser à deux options:

Une expression régulière:

QStringList sl = s.split(QRegularExpression("\n(?=Part [0-9]+|Section [A-Z]+)"));

Il semble que cela devrait fonctionner, mais parfois les exceptions passent (IE: Section SQL Entriesserait divisé par erreur)

Sinon, ce que je pourrais faire est de placer un marqueur lorsque je génère la chaîne initiale:

🚤💻 Partie 1
Bateau

🚤💻
Programmation de la section A

🚤💻Partie 2
Partitionnement des bateaux pour la programmation.

🚤💻Section AA
Section SQL Entrées.

Ce qui signifie que le fractionnement de la chaîne deviendrait facile:

QStringList sl = s.split("🚤💻"));

Quelque chose me dit cependant que ni l'un ni l'autre n'est un bon style ou une bonne pratique de programmation, mais jusqu'à présent, je n'en ai pas discuté ni trouvé d'alternative.

  • Si vous étiez mon chef de projet, accepteriez-vous l'une de ces méthodes?
  • Sinon, que suggéreriez-vous que je fasse comme meilleure pratique?
Akiva
la source
6
Si votre programme sait où placer ces marqueurs, pourquoi ne pas générer les sections en tant que chaînes distinctes pour commencer?
Jacob Raihle
Je ne pense pas que l'utilisateur un marqueur qui ne se traduit pas bien dans votre encodage actuel soit une bonne idée.
Tulains Córdova
2
les symboles réels utilisés sont largement hors de propos, ce qui va faire la différence, c'est la grammaire de la chose que vous essayez d'analyser
jk.
4
@Akiva êtes-vous sûr du succès des performances? Vous travaillez avec la même quantité de données dans tous les cas, je doute qu'il y aurait une différence significative. Composez les milliers de fonctions en une seule fonction, invoquez-la en boucle et prenez des mesures.
Jacob Raihle
2
@Akiva Récupérer et remplacer des éléments dans une liste devrait au pire être comparable au fractionnement d'une grosse chaîne.
Jacob Raihle

Réponses:

17

Ce n'est pas une mauvaise pratique que l'encodage de documents soit incorporé sous forme de texte dans une chaîne. Pensez au démarque, HTML, XML, JSON, YAML, LaTeX, etc.

Ce qui est une mauvaise pratique, c'est de réinventer la roue. Plutôt que d'écrire votre propre processeur de texte, pensez à utiliser une norme existante. Il existe de nombreux logiciels gratuits qui effectuent une grande partie de l'analyse pour vous, et beaucoup ont une licence non restrictive qui vous permet d'utiliser ledit logiciel dans votre propre logiciel propriétaire.

David Hammen
la source
Dans mon cas, j'invente une roue, si ce que j'essaie de faire est de construire un interprète unique pour un langage de démarque. Par exemple, l'un de mes projets consistait à interpréter Latex comme SSML lisible par l'oreille humaine: meta.wikimedia.org/wiki/Grants:IdeaLab/… . << Il y a un point à la fin de cette URL, sinon cela ne fonctionnera pas
Akiva
2
@Akiva Je dois travailler avec un format de texte personnalisé développé par mon lieu de travail qui réinvente littéralement la roue. Je dois maintenir 4 analyseurs en 3 langues (Javascript, Java et Objective-C) pour cela, et c'est un cauchemar effrayant . Faites ce qu'il faut maintenant et supprimez ce non-sens de format de texte personnalisé . Je ne saurais trop insister sur l' énorme cauchemar de maintenance que cela deviendra dans quelques années. Utilisez les formats structurés existants, XML, JSON, etc.
Chris Cirefice
@ChrisCirefice Pouvez-vous me donner un exemple de la façon dont c'est un cauchemar?
Akiva
1
@Akiva Je pense que le fait que vous devez maintenir un seul analyseur (dans mon cas plusieurs et dans différentes langues) est horrible. Les formats standard existent pour une raison - ils peuvent représenter les données dont vous avez besoin - et avec très peu d'efforts de votre part, car ces analyseurs ont été construits, affinés et maintenus. Le format de texte personnalisé est également une connaissance extrêmement spécialisée, ce qui signifie qu'en général, seuls un ou deux développeurs connaissent suffisamment le format pour le maintenir avec succès. Cela devrait en dire long. La plupart des gens connaissent CML, JSON - peu connaissent les formats personnalisés.
Chris Cirefice
1
@Akiva Effectivement! Le format Markdown (ce que SE et de nombreux autres sites utilisent pour la mise en forme du texte) est quelque peu standard , tout comme SQL. Mais il existe de nombreuses «saveurs» différentes avec des extensions personnalisées (par exemple, comme SE). Il existe une bibliothèque standard qui analyse le «noyau», puis vous étendez la bibliothèque si vous souhaitez des fonctionnalités supplémentaires. Mais construire et maintenir votre propre formateur serait ridicule - plusieurs existent déjà (démarque, code BB, etc.), alors pourquoi réinventer la roue et conserver tout ce code? Peut aussi bien utiliser une bibliothèque existante :)
Chris Cirefice
8

L'utilisation d'un séparateur commun devrait fonctionner correctement lors du fractionnement de chaînes arbitraires plus grandes, mais je déconseille d'utiliser un symbole arbitraire. Quelqu'un qui lit cette chaîne en texte brut peut être confondu, sans parler des problèmes avec UTF et si le symbole apparaît ou non à l'intérieur des sections.

La partie la plus importante de cela est que chaque section reste intacte, tandis que chaque "en-tête de section" doit être identifié de manière appropriée.

Pourquoi ne pas utiliser un séparateur commun mais le garder lisible? Quelque chose comme:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

Le problème est de décider ce que le séparateur doit être, car il doit être quelque chose qui est garanti pour ne pas afficher de section. Vous pouvez l'identifier en tant que séparateur en exigeant qu'il se trouve au début d'une ligne et le seul texte de cette ligne .

Sans autre connaissance du texte attendu dans chaque section, il est difficile de faire une recommandation sur le séparateur commun qui serait le mieux dans ce cas.

Erdrik Ironrose
la source
J'aime l'accent mis par votre réponse sur la lisibilité. Les chaînes sont générées par le grattage des données du texte généré par l'utilisateur, par exemple, le langage de balisage utilisé dans SE pour écrire des questions et des réponses. Ainsi, vous pouvez facilement imaginer quels types de problèmes de manipulation de chaînes pourraient entrer en jeu.
Akiva
5

La réponse acceptée semble avoir raté ce que vous avez écrit dans un commentaire:

La raison en est que la plupart des manipulations que je fais nécessitent la chaîne complète

et a donné ceci comme exemple:

à la place ("bateau", "programmation");

Si c'est ce que vous voulez, c'est à mon humble avis une très mauvaise idée d'utiliser un "markdown" ou un séparateur textuel pour toute votre chaîne, cela a toujours un certain risque d'interférer avec la manipulation et ne conduira pas à un code robuste. Surtout lorsque vous essayez de commencer à utiliser des expressions régulières sur une telle chaîne combinée, vous rencontrerez probablement les mêmes problèmes que ceux rencontrés lors de l'analyse de HTLM ou XML avec des expressions régulières .

Surtout parce que vous avez écrit qu'il pourrait y avoir "des milliers de fonctions [de manipulation]", ce risque pourrait devenir un vrai problème. Même si vous utilisez une démarque comme XML pour stocker la liste de chaînes en interne, vous devez vous assurer que la manipulation ne traitera que le contenu, pas la démarque, ce qui signifierait de diviser la chaîne en parties avant d'effectuer tout traitement et de rejoindre après cela à nouveau - de sorte que cela aura un risque élevé de vous donner une mauvaise performance.

La meilleure alternative de conception ici est de fournir un type de données abstrait (utilisez une classe si vous le souhaitez), de l'appeler MyStringListet de fournir un petit ensemble d'opérations de base qui vous permettent d'implémenter vos "milliers de fonctions" en termes de ces opérations. Par exemple, il peut y avoir des opérations génériques findet replaceou une mapopération fonctionnelle générique . Vous pouvez également ajouter quelque chose comme une JoinToStringopération si vous avez vraiment besoin de toute la liste dans une chaîne pour certains purporses.

En utilisant ces opérations, votre crainte que le code ne devienne plus compliqué parce que "tout devrait être fait dans une boucle for" devient inutile, car les seules forboucles que vous obtenez sont encapsulées dans les opérations du type de données. Et je ne serais pas préoccupé par les performances jusqu'à ce que vous ayez un impact réel et mesurable sur les performances (que je doute que vous obteniez si vous implémentez correctement les opérations de base).

Doc Brown
la source
Votez parce que j'ai créé quelque chose comme ça. Cela me permet de définir des crochets personnalisés, par exemple, <et >, et il saisira chaque instance de cette chaîne où je pourrai facilement supprimer les instances dont je ne veux pas, et les manipuler proprement de la manière que je veux. C'est bien parce que les expressions régulières seules ne gèrent pas les sous-chaînes comme ceci: <boat <programming>>bien là où il y a plusieurs couches de crochets.
Akiva
1

Le format décrit est très similaire aux fichiers INI:

https://en.wikipedia.org/wiki/INI_file

Dans ce cas, la section est entourée de crochets [], donc ce que vous décrivez a du sens en marquant la section d'une certaine manière pour ajouter une signification supplémentaire à ce texte.

Jon Raynor
la source
0

Par exemple, je pourrais générer une chaîne comme celle-ci:

Question: A partir de quoi "générez-vous" cette chaîne?

Serait- ce plus facile à manipuler?

Phill W.
la source
La chaîne est générée à partir du contenu utilisateur Datascraping d'un site Web.
Akiva
1
Ce n'est pas un moyen fiable de récupérer des données à partir d'un site Web, simplement parce qu'elles changent et que les choses bougent ou disparaissent complètement. Vous feriez bien mieux de récupérer les données d'une sorte d'API publiée (et donc fiable). De plus, l'utilisation de nombreux sites Web commerciaux interdit spécifiquement ce genre de choses.
Phill W.
Parfois, je ne peux pas choisir quelles données sont importantes pour moi, et il est donc toujours nécessaire de faire des vérifications d'intégrité pour ce que vous regardez, ou tout simplement un compromis et d'espérer pour le mieux. Par exemple: j'ai écrit un LaTeXà l' SSMLinterprète, et l'un des problèmes est que vous pouvez générer des images identiques avec un code très différent, et il est donc presque impossible d'être cohérent si l'utilisateur choisit des moyens médiocres ou ésotériques de générer ses formules. Tout cela signifie en fin de compte que les personnes qui n'utilisent pas de bonnes pratiques n'auront pas une interprétation décente de leurs scripts.
Akiva