Wie fett ist dieser Beitrag?

13

Präambel

In Stack Exchange Markdown verwenden wir **, um Text hervorzuheben. Zum Beispiel dieser Abschlag:

The **quick brown fox jumps over the lazy** dog.

Rendert als:

Der schnelle braune Fuchs springt über den faulen Hund.

Natürlich verwenden wir ** auch, um Kühnheit zu schließen. Die Antwort wird also weniger kühn sein. Beispielsweise:

The **quick** brown fox jumps over the **lazy** dog.

Rendert als:

Der schnelle braune Fuchs springt über den faulen Hund.

Wenn die Kühnheit jedoch nicht geschlossen ist, wird sie als nicht fett dargestellt :

The **quick brown fox jumps over the lazy dog.

Rendert als:

Der ** schnelle Braunfuchs springt über den faulen Hund.

Wenn der Text einen einzelnen Backslash enthält \, wird die Fettschrift auch nicht wirksam:

The \**quick brown fox jumps over the lazy dog.**

Rendert als:

Der ** schnelle braune Fuchs springt über den faulen Hund. **

Nachgestellte Leerzeichen führen zu nicht fettgedrucktem Text (beachten Sie, dass das Leerzeichen nach Braun eine einzelne Registerkarte ist):

The** quick** brown fox jumps over the lazy dog.**

Rendert als:

Der ** schnelle ** Braunfuchs springt über den faulen Hund. **

Wir können __ auch für Fettdruck verwenden, beachten Sie jedoch, dass immer nur einer aktiv sein kann. Hier ist ein komplizierteres Beispiel:

The __quick**__ brown **fox__ jumps** over__ the__ lazy **dog.

Rendert als:

Der schnelle braune Fuchs springt über den faulen Hund.

Die Frage:

Sie können ein Programm oder eine Funktion, da ASCII - Text entweder als schreiben StringArgument oder auf STDIN, wo die einzigen Sonderzeichen sind **, __, \(für die Flucht) und nachfolgende Leerzeichen, bestimmen , wie viele fett gedruckt sind. Dieser Wert sollte auf STDOUT gedruckt oder von Ihrer Funktion zurückgegeben werden. Sie müssen keine sehr langen Zeichenfolgen unterstützen. Die Zeichenfolgenlänge beträgt garantiert nicht mehr als 30K. Dies ist die Obergrenze für ein Stack Exchange-Posting.

Kleingedrucktes:

  • Kann ich für einen Fall eine Ausnahme / einen anderen Fehler auslösen und für den anderen normal zurückkehren?
    • Nein. In beiden Fällen muss es sich entweder um einen eindeutigen, fehlerfreien Rückgabewert handeln. STDERR-Ausgabe wird ignoriert.
  • Werden Leerzeichen zwischen Wörtern als fett angesehen?
    • Ja. **quick brown**enthält 11 fette Zeichen.
  • Sollte die \in \**, wenn fett, gezählt werden?
    • Nein, es wird als ** dargestellt. Wenn es also fett gedruckt sein sollte, sind es nur 2 Zeichen.
  • Sei ganz klar: Was meinst du mit wie vielen Zeichen?
    • Gesamtzahl der Zeichen, die fett dargestellt würden. Dies bedeutet , dass **wird nicht gerendert , wenn es sich um Text verwandelt, aber es gemacht wird , wenn es nicht.
    • Beachten Sie, **dass Fettdruck auf verschiedene Arten möglich ist, z . B. **\****-> ** .
    • Berücksichtigen Sie nicht die Möglichkeit, dass Text in Kursivschrift umgewandelt werden könnte. Die einzige zu berücksichtigende Abschriftenregel ist ** = fett *.
  • Bei Stack Exchange funktioniert auch HTML Bold. dh <b> </ b>
    • Ja, ich bin mir bewusst. Betrachten Sie diesen Fall nicht, dies ist normaler Text.
  • Was ist mit HTML-Elementen? zB &lt;-><
    • Diese sollten auch als normaler Text betrachtet werden, es findet keine HTML-Entitätskonvertierung statt.
  • Ich habe an ein Beispiel gedacht, das Sie oben nicht behandelt haben!
    • Die Regeln funktionieren genau so, als ob der Text in einer Antwort (kein Kommentar) auf Stack Exchange veröffentlicht worden wäre , mit der Ausnahme, dass Codeblöcke keine Sonderzeichen sind . Sowohl der Typ mit vier Leerzeichen als auch der Backtick-Typ. Wenn Sie sich nicht sicher sind, wie der Text gerendert werden soll, werfen Sie ihn zum Testen einfach in ein Antwortfeld. Dies sind die Regeln, die Sie befolgen sollten.

Beispiele:

Eingang:

The **quick brown fox jumps over the lazy** dog.

Ausgabe:

35

Eingang:

The **quick brown fox jumps over the lazy dog.

Ausgabe:

0

Eingang:

The __quick**__ brown **fox__ jumps** over__ the__ lazy **dog.

Ausgabe:

18

Eingang:

The __quick\____ brown fox **jumps over\** the** lazy \**dog.

Ausgabe:

23

Eingang:

The****quick brown fox****jumps over **the****lazy** dog.

Ausgabe:

11

Standardlücken sind verboten.

durron597
quelle
Stimmt das 18für den dritten Testfall?
Beta Decay
@BetaDecay Es ist 7 + 11. Was denkst du sollte es sein?
Durron597
Ich habe 28 ... Ich werde mein Programm
Beta Decay
@BetaDecay **fox__ jumps**beendet diese bestimmte Fettschrift.
Durron597
1
Die Frage scheint darauf hinzudeuten , dass \**oder \__Escape - Sequenzen aus drei Zeichen sind, aber in Stack gibt es nur zwei Zeichen Escape - Sequenzen \*oder \_. So \***a**erzeugt ein Stern von einem mutigen gefolgt a. Es gibt auch eine andere Flucht \\ . Sollen wir damit umgehen?
Feersum

Antworten:

5

RS , 107 Bytes

\t/ 
(?<!\\)((\*|_){2})((?=\S)(?!\2)(\\\2|.)*?)?(?<=\S)\1/(\n)^^((^^\3))\3
\\(\*|_)/\t
[^\t\n]/
\n/_
\t_?/
(_*)/(^^\1)

Live-Demo und Testfälle.

Das ist eine ziemlich verrückte Sache.

Der neueste Testfall funktioniert noch nicht. WIP ...

Erläuterung

\t/ 

Ersetzen Sie Tabulatoren durch Leerzeichen. Sie haben die gleiche Zeichenanzahl und Tabulatoren werden später als Sonderzeichen verwendet.

(?<!\\)((\*|_){2})((?=\S)(?!\2)(\\\2|.)*?)?(?<=\S)\1/(\n)^^((^^\3))\3

Ersetzen Sie alle Texte mit einer Länge N, die fett Ngedruckt werden sollen, durch Zeilenumbrüche, gefolgt vom Originaltext.

\\(\*|_)/\t

Ersetzen Sie alle Vorkommen eines Trennzeichens, denen ein Schrägstrich unmittelbar vorausgeht, durch einen Tabulator. Dies soll sicherstellen, dass Einträge wie **a\***eine Zeichenanzahl von 2 anstelle von 3 haben.

[^\t\n]/

Entfernen Sie alle Zeichen, die keine Tabulatoren oder Zeilenumbrüche sind.

\n/_

Ersetzen Sie alle Zeilenumbrüche durch Unterstriche.

\t_?/

Entfernen Sie alle Tabulatoren (die Begrenzungszeichen mit Escapezeichen darstellen) sowie alle darauf folgenden Unterstriche. Dies hängt mit dem obigen Problem der Zeichenzählung mit Begrenzungszeichen mit Escapezeichen zusammen.

(_*)/(^^\1)

Ersetzen Sie die Unterstrichsequenz durch ihre Länge. Dies ist die Zeichenanzahl.

kirbyfan64sos
quelle
**a****b**Ausgänge 2, sollte es 6 sein. Siehe: a **** b
durron597
1
@ durron597 Ich bin etwas verwirrt, wie das funktionieren soll. Könnten Sie eine Erklärung hinzufügen?
kirbyfan64sos
Wie ich schon sagte, spiele einfach in einem Antwortfenster damit herum. **** ist immer nur ein Sternchen, das in einem Fettdruck oder nicht in einem Fettdruck basierend auf dem anderen Text stehen kann.
Durron597
Also, @ kirbyfan64sos, wie fett ist die Post?
mbomb007
2

Python: 133 Zeichen

import re
f=lambda s:sum(len(x[0])-4for x in re.findall(r'(([_*])\2\S.*?\2\2+)',re.sub(r'([_*])\1\1\1','xxxx',re.sub(r'\\.','x',s))))

Dies sollte sowohl in Python 2 als auch in Python 3 identisch funktionieren. Die Funktion fgibt die Anzahl der fetten Zeichen in der Zeichenfolge zurück, die beim Formatieren mit dem Markdown-System von Stack Overflow übergeben wird.

Ich glaube, ich habe die meisten Eckfälle richtig verstanden (einschließlich aller in den Kommentaren erwähnten Fälle), aber es ist immer noch nicht ganz perfekt. Ich verstehe nicht, warum x***x**das nicht *xfett dargestellt wird (wie es der ***x**Fall ist), sodass mein Code mindestens einige falsche Eingaben erhält.

Der Code besteht aus vier Hauptschritten. Der erste Befehl ersetzt einen beliebigen umgekehrten Schrägstrich durch einen regulären Ausdruck, gefolgt von einem beliebigen Zeichen mit einem 'x'. Der zweite Schritt ersetzt eine beliebige Folge von vier Sternchen oder Unterstrichen durch vier 'x' Zeichen. Der dritte Schritt verwendet einen regulären Ausdruck findall, um alle Blöcke zu finden, die kursiv gedruckt werden. Der letzte Schritt ist ein Generatorausdruck innerhalb eines sumAufrufs, der die Länge dieser Blöcke addiert und jeweils 4 Zeichen abzieht, da wir die Begrenzer nicht in unsere Zählung einbeziehen möchten.

Hier sind einige Testausgaben:

>>> f('The **quick brown fox jumps over the lazy** dog.')
35
>>> f('The **quick brown fox jumps over the lazy dog.')
0
>>> f('The \**quick brown fox jumps over the lazy dog.**')
0
>>> f('The** quick** brown fox jumps over the lazy dog.**')
0
>>> f('The __quick\____ brown fox **jumps over\** the** lazy \**dog.')
23
>>> f('The****quick brown fox****jumps over **the****lazy** dog.')
11
>>> f('\***a**')
1
>>> f('x***x**') # this one doesn't match the Stack Overflow input box
2
Blckknght
quelle
Ich habe keine Ahnung warum x***x**das nicht im Eingabefeld funktioniert. Bizarre
durron597
1

JavaScript ES6, 91 Byte

s=>(o=0,s.replace(/\\(.)\1/g,'..').replace(/(\*\*|__)(?=\S)(.*?\S)\1/g,l=>o+=l.length-4),o)

Behandelt alle Escapezeichen vor Hand und verwendet dann einen regulären Ausdruck. Viel Golfpotential.

Erläuterung

s=>( // Function with argument s
  o=0, // Set var "o" to 0
  s.replace( // Replace...
    /\\(.)\1/g,  // Matches \ followed by two the same characters. g means "global"
    ".." // Replace with two arbitrary characters
  ).replace( // Replace again...
     /(\*\*|__) // Match ** or __, store in "group 1"
       (?=\S)   // Make sure next character isn't whitespace
       (.*?\S)\1  // Match all characters until "group 1".
                  // Make sure last character isn't whitespace
     /g, l=> // Take the match...
       o+= // Increase o by...
         l.length // the length of the match
         - 4 // minus 4 to account for ** and __
  ), o) // Return o
Downgoat
quelle
Dafür **a*b*c**gibt es 9 zurück, was ich für falsch halte. Die tatsächliche Anzahl beträgt 5 (oder 3, wenn Sie Kursivschrift berücksichtigen, was Sie laut OP nicht tun sollten).
Cristian Lupascu