Ist das Platzieren von Textmarkierungen innerhalb von Zeichenfolgen ein schlechter Stil? Gibt es eine Alternative?

10

Ich arbeite mit massiven Saiten, die viel Manipulation erfordern.

Zum Beispiel könnte ich eine Zeichenfolge wie folgt generieren:

Teil 1
Boot

Abschnitt A
Programmierung

Teil 2
Partitionieren von Booten zum Programmieren.

Abschnitt AA
Abschnitt SQL-Einträge.

Die Zeichenfolge wäre zu groß, um jeden Teil manuell zu überprüfen. Jetzt muss ich splitdies stringin stringlistAbschnitte und Teile umwandeln. Ich kann mir zwei Möglichkeiten vorstellen:

Ein regulärer Ausdruck:

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

Das sieht so aus, als ob es funktionieren sollte, aber manchmal rutschen Ausnahmen durch (IE: Section SQL Entrieswürde fälschlicherweise aufgeteilt werden)

Andernfalls könnte ich beim Generieren der ersten Zeichenfolge einen Marker setzen:

🚤💻Teil 1
Boot

🚤💻Abschnitt A
Programmierung

🚤💻Teil 2
Partitionieren von Booten zum Programmieren.

🚤💻
Abschnitt SQL-Einträge des Abschnitts AA .

Was bedeutet, dass das Teilen der Zeichenfolge einfach wird:

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

Etwas sagt mir zwar, dass keines davon ein guter Stil oder eine gute Programmierpraxis ist, aber ich habe bis zu diesem Punkt weder darüber gesprochen noch eine Alternative gefunden.

  • Wenn Sie mein Projektmanager wären, würden Sie eine dieser Methoden akzeptieren?
  • Wenn nicht, was würden Sie mir als Best Practice vorschlagen?
Akiva
quelle
6
Wenn Ihr Programm weiß, wo diese Markierungen platziert werden sollen, generieren Sie die Abschnitte zunächst als separate Zeichenfolgen.
Jacob Raihle
Ich denke nicht, dass Benutzer einen Marker, der sich nicht gut in Ihre aktuelle Codierung übersetzen lässt, eine gute Idee ist.
Tulains Córdova
2
Die tatsächlich verwendeten Symbole sind weitgehend irrelevant. Was einen Unterschied machen wird, ist die Grammatik der Sache, die Sie analysieren
möchten
4
@Akiva bist du dir über den Performance-Hit sicher? Sie arbeiten auf jeden Fall mit der gleichen Datenmenge, ich bezweifle, dass es einen signifikanten Unterschied geben würde. Stellen Sie die Tausenden von Funktionen zu einer Funktion zusammen, rufen Sie diese in einer Schleife auf und nehmen Sie einige Messungen vor.
Jacob Raihle
2
@Akiva Das Abrufen und Ersetzen von Elementen in einer Liste sollte im schlimmsten Fall mit dem Teilen einer großen Zeichenfolge vergleichbar sein.
Jacob Raihle

Antworten:

17

Es ist keine schlechte Praxis, die Dokumentcodierung als Text in eine Zeichenfolge einzubetten. Denken Sie an Markdown, HTML, XML, JSON, YAML, LaTeX usw.

Was schlechte Praxis ist, ist das Rad neu zu erfinden. Anstatt einen eigenen Textprozessor zu schreiben, sollten Sie einen vorhandenen Standard verwenden. Es gibt viele freie Software, die einen Großteil des Parsens für Sie erledigt, und viele verfügen über eine nicht einschränkende Lizenz, mit der Sie diese Software in Ihrer eigenen proprietären Software verwenden können.

David Hammen
quelle
In meinem Fall erfinde ich ein Rad, wenn ich versuche, einen einzigartigen Interpreter für eine Abschriftensprache zu erstellen. Eines meiner Projekte war beispielsweise die Interpretation von Latex als SSML, das vom menschlichen Ohr gelesen werden kann : meta.wikimedia.org/wiki/Grants:IdeaLab/… . << Es gibt einen Punkt am Ende dieser URL, sonst funktioniert es nicht
Akiva
2
@Akiva Ich muss mit einem von meinem Arbeitsplatz entwickelten benutzerdefinierten Textformat arbeiten, das das Rad buchstäblich neu erfindet. Ich muss dafür 4 Parser in 3 Sprachen (Javascript, Java und Objective-C) verwalten, und es ist ein verdammter Albtraum . Tun Sie jetzt das Richtige und beseitigen Sie diesen Unsinn im benutzerdefinierten Textformat . Ich kann gar nicht genug betonen, wie groß der Alptraum für die Instandhaltung in ein paar Jahren sein wird. Verwenden Sie vorhandene strukturierte Formate, XML, JSON usw.
Chris Cirefice
@ChrisCirefice Kannst du mir ein Beispiel geben, wie es ein Albtraum ist?
Akiva
1
@Akiva Ich finde die Tatsache, dass Sie auch nur einen Parser (in meinem Fall mehrere und in verschiedenen Sprachen) pflegen müssen, schrecklich. Standardformate gibt es aus einem bestimmten Grund - sie können die Daten darstellen, für die Sie sie benötigen - und mit äußerst geringem Aufwand, da diese Parser erstellt, verfeinert und verwaltet wurden. Das benutzerdefinierte Textformat ist auch äußerst spezialisiert, was bedeutet, dass normalerweise nur ein oder zwei Entwickler mit dem Format vertraut genug sind, um es erfolgreich zu verwalten. Das sollte Bände sprechen. Die meisten Menschen sind mit CML und JSON vertraut - nur wenige kennen benutzerdefinierte Formate.
Chris Cirefice
1
@ Akiva In der Tat! Das Markdown-Format (was SE und viele andere Websites für die Textformatierung verwenden) ist etwas Standard , wie es SQL ist. Es gibt jedoch viele verschiedene "Geschmacksrichtungen" mit benutzerdefinierten Erweiterungen (z. B. SE). Es gibt eine Standardbibliothek, die den 'Kern' analysiert. Wenn Sie zusätzliche Funktionen wünschen, erweitern Sie die Bibliothek. Das Erstellen und Verwalten eines eigenen Formatierers wäre jedoch lächerlich - es gibt bereits mehrere (Abschriften, BB-Code usw.). Warum also das Rad neu erfinden und den gesamten Code beibehalten?
Kann
8

Die Verwendung eines gemeinsamen Trennzeichens sollte beim Teilen größerer beliebiger Zeichenfolgen gut funktionieren, ich würde jedoch empfehlen, kein beliebiges Symbol zu verwenden. Jemand, der diese Zeichenfolge als Klartext liest, könnte verwirrt sein, ganz zu schweigen von Problemen mit UTF und davon, ob das Symbol in den Abschnitten angezeigt wird oder nicht.

Der wichtigste Teil davon ist, dass jeder Abschnitt intakt bleibt, während jeder "Abschnittskopf" entsprechend identifiziert werden muss.

Warum nicht ein gemeinsames Trennzeichen verwenden, aber lesbar halten? Etwas wie:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

Das Problem besteht darin, zu entscheiden, was das Trennzeichen sein soll, da es etwas sein muss, das garantiert keinen Abschnitt anzeigt. Sie können es außerdem als Trennzeichen identifizieren, indem Sie festlegen, dass es sich am Anfang einer Zeile befindet und der einzige Text in dieser Zeile ist .

Ohne weitere Kenntnisse darüber, welcher Text in den einzelnen Abschnitten erwartet wird, ist es schwierig, eine Empfehlung abzugeben, welches gemeinsame Trennzeichen in diesem Fall am besten geeignet ist.

Erdrik Ironrose
quelle
Ich mag die Betonung Ihrer Antwort auf Lesbarkeit. Die Zeichenfolgen werden durch Datenerfassung von benutzergeneriertem Text generiert, z. B. die in SE zum Schreiben von Fragen und Antworten verwendete Markup-Sprache. So können Sie sich leicht vorstellen, welche Probleme bei der Manipulation von Saiten ins Spiel kommen könnten.
Akiva
5

Die akzeptierte Antwort scheint verfehlt zu haben, was Sie in einem Kommentar geschrieben haben:

Der Grund ist, dass für viele meiner Manipulationen die vollständige Zeichenfolge erforderlich ist

und gab dies als Beispiel:

s.replace ("Boot", "Programmierung");

Wenn es das ist, was Sie wollen, ist es meiner Meinung nach eine wirklich schlechte Idee, einen "Markdown" oder ein Texttrennzeichen für Ihre gesamte Zeichenfolge zu verwenden. Dies birgt immer ein gewisses Risiko, die Manipulation zu stören, und führt nicht zu robustem Code. Insbesondere wenn Sie versuchen, reguläre Ausdrücke für eine solche kombinierte Zeichenfolge zu verwenden, werden Sie wahrscheinlich auf dieselben Probleme stoßen, die beim Parsen von HTLM oder XML mit regulären Ausdrücken auftreten .

Insbesondere, weil Sie geschrieben haben, dass es "Tausende von [solchen Manipulations-] Funktionen" geben könnte, könnte dieses Risiko zu einem echten Problem werden. Selbst wenn Sie einen Markdown wie XML verwenden, um die Zeichenfolgenliste intern zu speichern, müssen Sie sicherstellen, dass bei der Manipulation nur der Inhalt und nicht der Markdown verarbeitet wird. Dies bedeutet, dass Sie die Zeichenfolge vor der Verarbeitung in Teile aufteilen und beitreten müssen es danach wieder - so dass ein hohes Risiko besteht, dass Sie eine schlechte Leistung erbringen.

Die bessere Entwurfsalternative besteht darin, einen abstrakten Datentyp bereitzustellen (verwenden Sie eine Klasse, wenn Sie möchten), sie aufzurufen MyStringListund einen kleinen Satz grundlegender Operationen bereitzustellen, mit denen Sie Ihre "Tausenden von Funktionen" in Bezug auf diese Operationen implementieren können. Zum Beispiel könnte es generisch sein findund replaceOperationen oder einen generischen funktionalen mapBetrieb . Sie können auch so etwas wie eine JoinToStringOperation hinzufügen, wenn Sie für bestimmte Zwecke wirklich die gesamte Liste in einer Zeichenfolge benötigen.

Wenn Sie diese Operationen verwenden, wird Ihre Befürchtung, dass der Code komplizierter wird, weil "alles in einer for-Schleife erledigt werden müsste", sinnlos, da die einzigen forSchleifen, die Sie erhalten, in den Operationen des Datentyps gekapselt sind. Und ich würde mir keine Sorgen um die Leistung machen, bis Sie eine echte, messbare Auswirkung auf die Leistung haben (was ich bezweifle, dass Sie sie erhalten, wenn Sie die grundlegenden Operationen korrekt implementieren).

Doc Brown
quelle
Upvote, weil ich so etwas tatsächlich erstellt habe. Es ermöglicht mir, benutzerdefinierte Klammern zu setzen, <und >, und es wird jede Instanz dieser Zeichenfolge erfassen, wo ich die Instanzen, die ich nicht möchte, leicht entfernen und sie sauber auf die gewünschte Weise bearbeiten kann. Dies ist gut, da reguläre Ausdrücke für sich genommen keine Teilzeichenfolgen wie diese verarbeiten: Nun, <boat <programming>>wenn mehrere Ebenen von Klammern vorhanden sind.
Akiva
1

Das beschriebene Format ist INI-Dateien sehr ähnlich:

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

In diesem Fall wird der Abschnitt in eckige Klammern [] eingeschlossen. Was Sie also beschreiben, ist sinnvoll, indem Sie den Abschnitt auf irgendeine Weise markieren, um diesem Text eine zusätzliche Bedeutung zu verleihen.

Jon Raynor
quelle
0

Zum Beispiel könnte ich eine Zeichenfolge wie folgt generieren:

Frage: Woraus "generieren" Sie diesen String?

Wäre das einfacher zu manipulieren?

Phill W.
quelle
Die Zeichenfolge wird aus Datascraping-Benutzerinhalten einer Website generiert.
Akiva
1
Dies ist keine zuverlässige Methode zum Abrufen von Daten von einer Website, einfach weil sie sich ändern und Dinge verschoben werden oder ganz verschwinden. Sie sind weitaus besser dran, die Daten von einer veröffentlichten (und daher zuverlässigen) API abzurufen. Darüber hinaus verbietet die Nutzung vieler kommerzieller Websites diese Art von Dingen.
Phill W.
Manchmal kann ich nicht entscheiden, welche Daten für mich wertvoll sind, und daher müssen immer Integritätsprüfungen für das durchgeführt werden, was Sie sich ansehen, oder einfach nur Kompromisse eingehen und auf das Beste hoffen. Zum Beispiel: Ich schrieb eine LaTeXauf SSMLDolmetscher, und eines der Probleme ist , dass Sie identische Bilder mit sehr unterschiedlichem Code erzeugen können, und so ist es nahezu unmöglich , konsequent zu sein , wenn der Benutzer seine Formeln zu erzeugen , schlecht oder esoterische Wege wählt. Letztendlich bedeutet dies nur, dass Menschen, die keine guten Praktiken anwenden, keine anständige Interpretation ihrer Skripte haben.
Akiva