Reduzieren Sie HTML auf n Zeichen, während Sie die Formatierung beibehalten

11

Fast jede Sprache verfügt über eine integrierte Funktion, mit der eine Zeichenfolge an einer bestimmten Position aufgeteilt werden kann. Sobald Sie jedoch HTML-Tags in der Zeichenfolge haben, funktioniert die integrierte Funktion nicht mehr ordnungsgemäß.

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die eine Zeichenfolge am n-ten Zeichen aufteilt, jedoch keine Zeichen von HTML-Tags zählt und ein gültiges HTML ausgibt. Das Programm muss die Formatierung beibehalten. Leerzeichen außerhalb der HTML-Tags können nach Ihren Wünschen gezählt oder nicht gezählt werden, müssen jedoch beibehalten werden. Sie können jedoch mehrere aufeinanderfolgende Leerzeichen in einem einzigen Leerzeichen austauschen.

Eingang:

  1. die Saite
  2. die zu teilende Position bei (0-basiert)

Diese können als Programm- oder Funktionsargumente verwendet oder von der Standardeingabe gelesen werden.

Ausgabe: Die geteilte Zeichenfolge, die zurückgegeben oder in die Standardausgabe geschrieben werden kann.

Die Eingabe ist eine gültige HTML-Datei und enthält keine Entitäten (z. B.  ). Tags, die nach der Zeichenbegrenzung geöffnet werden, sollten in der Ausgabe weggelassen werden (siehe letztes Beispiel).

Beispiel:

Eingabe : <i>test</i>, 3
Ausgabe:<i>tes</i>

Eingabe : <strong><i>more</i> <span style="color: red">complicated</span></strong>, 7
Ausgabe:<strong><i>more</i> <span style="color: red">co</span></strong>

Eingabe : no html, 2
Ausgabe:no

Eingabe : <b>no</b> <i>html root</i>, 5
Ausgabe:<b>no</b> <i>ht</i>

Eingabe : <b>no img</b><img src="test.png" />more text, 6
Ausgabe:<b>no img</b>

Sie können jede Sprache und die Standardbibliothek der jeweiligen Sprache verwenden. Dies ist Code Golf, kürzeste Programmgewinne. Habe Spaß!

David Frank
quelle
1
Kann die Eingabe "<" und ">" enthalten, die nicht Teil eines HTML-Tags sind?
XEM
Man sollte &lt;und &gt;stattdessen verwenden <>, also nein ( &lt;oder &gt;auch nicht vorhanden sein).
David Frank
Könnten Sie ein Beispiel einfügen, bei dem nach dem Textknoten, an dem die Aufteilung erfolgt, ein Markup vorhanden ist ? Wie <i>ab</i><b>cd</b> 1?
Martin Ender
Gibt es andere Möglichkeiten als <i>a</i>?
David Frank
@ DavidFrank <i>a</i><b></b>(Was Sinn macht, wenn man bedenkt, dass bdas auch divoder sein könnte img.)
Martin Ender

Antworten:

2

Diese Antwort ist mit der neuesten Regel nicht mehr gültig.

Javascript ( ES6 ) 94 91

f=(s,l)=>s.split(/(<[^>]+>)/).map(x=>x[0]=='<'?x:[l-->0?y:''for(y of x)].join('')).join('')
f('<strong><i>more</i> <span style="color: red">complicated</span></strong>', 7);
// '<strong><i>more</i> <span style="color: red">co</span></strong>'

Ungolfed:

f=(s,l)=>
    s.split(/(<[^>]+>)/). // split string s by <*>, capture group is spliced into the array 
    map(x=> // map function to every item in the array
        x[0]=='<'? // if first character is a <
            x // don't modify the string
        : // else
            [ // array comprehension
                for(y of x) // for every character y in x
                    l-->0? // if l > 0 (and decrement l)
                        y // character y
                    : // else
                        '' // empty string 
            ].join('') // join characters in array
        ).
    join('') // join all strings in array
nderscore
quelle
Könnten Sie bitte den Code ohne Golf angeben oder nur erklären, was und warum der Code funktioniert? Es ist derzeit ein bisschen schwer zu verstehen. Vielen Dank!
Gaurang Tandon
@ GaurangTandon fügte ungolfed Code mit Kommentaren hinzu
nderscore
2

Rebol - 252 Zeichen

c: complement charset"<>"f: func[s n][t: e: 0 to-string collect[parse s[any[(m: 0)copy w[["</"some c">"](-- t)|["<"some c"/>"]|["<"some c">"](++ t)| any c(m: 1)](if e = 0[if m = 1[w: copy/part w n n: n - length? w]keep w]if all[n <= 0 t = 0][e: 1])]]]]

Ungolfed mit Kommentaren:

c: complement charset "<>"

f: func [s n] [
    t: e: 0             ;; tag level (nesting) & end output flag
    to-string collect [
        parse s [
            any [
                (m: 0)                            ;; tag mode
                copy w [
                      ["</" some c ">" ] (-- t)   ;; close tag
                    | ["<"  some c "/>"]          ;; self-closing / void elements
                    | ["<"  some c ">" ] (++ t)   ;; open tag
                    | any c (m: 1)                ;; text mode
                ] (
                    ;; flag not set so can still output
                    if e = 0 [
                        ;; in text mode - so trim text
                        if m = 1 [
                            w: copy/part w n
                            n: n - length? w
                        ]
                        keep w
                    ]

                    ; if all trimmed and returned to flat tag level then end future output
                    if all [n <= 0  t = 0] [e: 1]
                )
            ]
        ]
    ]
]

Beispiele in der Rebol-Konsole:

>> f "<i>test</i>" 3
== "<i>tes</i>"

>> f {<strong><i>more</i> <span style="color: red">complicated</span></strong>} 7
== {<strong><i>more</i> <span style="color: red">co</span></strong>}

>> f {no html} 2
== "no"

>> f {<b>no</b> <i>html root</i>} 5
== "<b>no</b> <i>ht</i>"

>> f {<b>no img</b><img src="test.png" />more text} 6
== "<b>no img</b>"

>> f {<i>a</i><b></b>} 1
== "<i>a</i>"

>> f {<strong><i>even</i> <span style="color: red">more <b>difficult</b></span></strong>} 14
== {<strong><i>even</i> <span style="color: red">more <b>diff</b></span></strong>}

>> f {<strong><i>even</i> <span style="color: red">more <b>difficult</b></span></strong>} 3 
== {<strong><i>eve</i><span style="color: red"><b></b></span></strong>}
draegtun
quelle
Dies verstößt erneut gegen die letzte Regel: Tags, die nach der Zeichenbegrenzung geöffnet werden, sollten in der Ausgabe weggelassen werden (siehe letztes Beispiel). Im letzten Beispiel sollten die Tags span und b weggelassen werden. Diese Regel macht die Herausforderung fast unmöglich.
edc65
@ edc65 - Leider hat (@David Frank) seine Beispiele nicht kommentiert oder aktualisiert, so dass unklar ist, ob er dieses Verhalten will oder nicht? Ich hatte gehofft, mein letztes Beispiel würde etwas bewegen! Ich werde gehen wie es ist, bis wir eine Klärung bekommen. Auf jeden Fall wären nur weitere 17 Zeichen erforderlich, damit es so funktioniert, wie Sie es vorgeschlagen haben. Ich mochte den Hack nicht besonders, also schrieb ich ihn stattdessen hier um (ungolfed) - gist.github.com/draegtun/93682f5a07c40bd86e31
draegtun
0

Ruby ... Sehr unrubylike mit Schleifen

def split(str,n)

  i = current = 0 
  return_str = ""

  while i < n
    if str[current] == "<"
      while str[current] != ">"
        return_str.concat str[current]
        current += 1
      end
      return_str.concat str[current]
      current += 1
    else
      return_str.concat str[current]
      i += 1
      current += 1
    end
  end

  while current < str.length
    if str[current] == "<"
      while str[current] != ">"
        return_str.concat str[current]
        current += 1
      end
      return_str.concat str[current]
      current += 1
    end
    current += 1
  end


  return_str + str[current..-1]
end
user26900
quelle
Diese Frage ist als Codegolf markiert, Sie sollten Ihre Antwort Golf spielen. Sie können beginnen, indem Sie die Variablennamen durch Namen mit einem Buchstaben ersetzen, kürzere Funktionsnamen verwenden und Leerzeichen entfernen, wo immer Sie können
sagiksp
0

(IE) JS - 135

function f(t,n){b=document.body;b.innerHTML=t;r=b.createTextRange();r.moveStart("character",n);r.select();r.execCommand('cut');return b.innerHTML}

Jetzt fühle ich mich schmutzig. Aber müssen anfangen, all diese Zeichen zu entfernen ...

function f(t,n)
{b=document.body;b.innerHTML=t;r=b.createTextRange();r.collapse();r.moveEnd("character",n);
r.select();return r.htmlText}

Haftungsausschluss:

  • in der IE-Konsole ausführen
eithed
quelle
1
Dies verstößt gegen die letzte (verrückte) Regel: Tags, die nach der Zeichenbeschränkung geöffnet werden, sollten in der Ausgabe weggelassen werden (versuchen Sie mein Beispiel in den obigen Kommentaren).
edc65
@ edc65 hoffentlich aktualisiert aktualisierte Version alle Regeln
eithed