Зменшіть html до n символів, зберігаючи форматування


11

Майже в кожній мові є вбудована функція, яка може розділити рядок у заданій позиції. Однак, як тільки у вас є теги html у рядку, вбудована функція не працюватиме належним чином.

Ваше завдання - написати програму або функцію, яка розбиває рядок на n-му символі, але не рахує символів тегів html та видасть дійсний html. Програма повинна зберігати форматування. Простіри поза тегами html можуть бути перераховані або не зараховані, як ви хочете, але повинні бути збережені. Однак ви можете обмінятися декількома послідовними пробілами в один простір.

Вхід:

  1. рядок
  2. позиція для поділу на (на основі 0)

Вони можуть сприйматися як програмні або функціональні аргументи або можуть бути прочитані зі стандартного вводу.

Вихід: розділений рядок, який можна повернути або записати на стандартний вихід.

Вхід буде дійсним html, він не буде містити жодних сутностей (наприклад,  ). Теги, які відкриваються після обмеження символів, слід випустити з виводу (див. Останній приклад).

Приклад:

Вхід:, <i>test</i>3
вихід:<i>tes</i>

Вхід:, <strong><i>more</i> <span style="color: red">complicated</span></strong>7
Вихід:<strong><i>more</i> <span style="color: red">co</span></strong>

Вхід:, no html2
вихід:no

Вхід:, <b>no</b> <i>html root</i>5
Вихід:<b>no</b> <i>ht</i>

Вхід:, <b>no img</b><img src="test.png" />more text6
Вихід:<b>no img</b>

Ви можете використовувати будь-яку мову та стандартну бібліотеку даної мови. Це кодовий гольф, найкоротша перемога програми. Веселіться!


1
чи може вхід містити "<" s та ">" s, які не є частиною тегу HTML?
xem

Слід використовувати &lt;і &gt;замість цього <>, так що жодного ( &lt;або його &gt;також не буде).
Девід Френк

Чи можете ви включити приклад, коли після текстового вузла, де відбувається розщеплення, розмічається розмітка ? Як <i>ab</i><b>cd</b> 1?
Мартін Ендер

Чи є інші варіанти, крім <i>a</i>?
Девід Френк

@DavidFrank <i>a</i><b></b>(Що має сенс, якщо ви вважаєте, що bце теж може бути divабо img.)
Martin Ender

Відповіді:


2

Ця відповідь більше не є дійсною з останнім правилом.

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>'

Безголівки:

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

Надайте, будь ласка, код, який не використовується для гольфу, чи, можливо, просто поясніть, що і чому код робить? Наразі його трохи важко зрозуміти. Дякую!
Gaurang Tandon

@GaurangTandon додав код neololfed з коментарями
nderscore

2

Ребол - 252 символи

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])]]]]

Неозолоті з коментарями:

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]
                )
            ]
        ]
    ]
]

Приклади в консолі Rebol:

>> 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>}

Знову ж це порушує останнє правило: теги, які відкриваються після обмеження символів, слід випустити з виводу (див. Останній приклад). В останньому прикладі теги span та b слід опустити. Це правило робить виклик майже неможливим.
edc65

@ edc65 - На жаль (@David Frank) не коментував і не оновлював своїх прикладів, тому незрозуміло, хоче він такої поведінки чи ні? Я сподівався, що мій останній приклад щось порушить! Вирушаємо так само, поки не отримаємо роз'яснення. У будь-якому разі знадобиться лише додаткові 17 символів, щоб він працював так, як ви запропонували. Мені особливо не подобався хак, тому замість цього переписав його тут (ungolfed) - gist.github.com/draegtun/93682f5a07c40bd86e31
draegtun

0

Рубін ... Дуже unrubylike з петлями

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

Це запитання позначене як кодовий гольф, вам слід відповісти на відповідь. Почати можна, замінивши імена змінних на одні літери, використовуючи короткі назви функцій та видаляючи пробіл, де можна
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}

Зараз я відчуваю себе брудно. Але потрібно почати видаляти всі ці ознаки ...

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

Відмова:

  • запустити в консолі IE

1
Це порушення останнього (шаленого) правила: Теги, які відкриваються після обмеження символів, слід випустити з виводу (спробуйте мій приклад у коментарях вище).
edc65

@ Edc65 ми сподіваємося, оновлена версія перевірки за всіма правилами
eithed
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.