Учитывая строку HTML, как лучше всего искать плавающие <> - PullRequest
0 голосов
/ 28 сентября 2019

Учитывая строку HTML:

myhtml = "<title> my title </title>"

Как я могу написать функцию, которая возвращает true, если есть плавающий / неэкранированный < или > вместе с самим символом-нарушителем?Примеры:

myhtml = "<title> my title </title>"
hasFloating(myhtml) => false

myhtml = "<title> < </title>"
hasFloating(myhtml) => true, <

myhtml = "<title> > </title>"
hasFloating(myhtml) => true, >

Имейте в виду, что эта строка может быть одним огромным фрагментом HTML-кода с несколькими элементами в нем.Я также согласен с одной функцией, проверяющей, существует ли неэкранированный символ, и второй, возвращающей сам символ нарушителя

Редактировать: для записи, я также использую камень mechanize в этом проекте

Ответы [ 3 ]

0 голосов
/ 28 сентября 2019

Я не собираюсь вдаваться в часть HTML, поскольку написание анализатора HTML - это сам проект.

Вы можете вернуть несколько значений, просто возвращая массив.

def hasFloating(html)
  # extract a < or > character surrounded by two spaces
  char = html[/(?<= )[<>](?= )/]
  [!!char, char] # !!char converts char into a boolean
end

Затем используйте декомпозиция массива , чтобы извлечь значения:

bool, char = hasFloating("<title> my title </title>") # bool = false, char = nil
bool, char = hasFloating("<title> < </title>")        # bool = true,  char = "<"
bool, char = hasFloating("<title> > </title>")        # bool = true,  char = ">"
0 голосов
/ 28 сентября 2019

Я думаю, что нашел ответ, используя nokogiri gem:

htmlStr = Nokogiri::HTML(html).text
# check for < or > in htmlSTR

Он в основном анализирует HTML и удаляет все теги:

html = <title> < </title>
# parse with nokogiri
=> " < "

Что может бытьиспользуется для проверки плавающего <>.

0 голосов
/ 28 сентября 2019

Если вы просто хотите проверить, есть ли угловая скобка, которая не закрыта, вам не нужен причудливый драгоценный камень.
Вы можете просто использовать StringScanner.

require 'strscan'

def has_floating(html)
  open_angle = 0
  scanner = StringScanner.new(html)
  while scanner.scan(/<|>/)
    case scanner.matched
    when '<'
      return [true, '<'] if open_angle == 1
      open_angle += 1
    when '>'
      return [true, '>'] if open_angle == 0
      open_angle -= 1
    end
    scanner.scan_until(/[^<>]+/)
  end
  return false
end

myhtml = "<title> my title </title>"
puts has_floating(myhtml).inspect
#=> false

myhtml = "<title> < </title>"
puts has_floating(myhtml).inspect
#=> [true, "<"]

myhtml = "<title> > </title>"
puts has_floating(myhtml).inspect
#=> [true, ">"]
...