Задачі №6-17

  1. Дано рядок тексту, вивести усі числа, які є у тексті.
  2. Дано рядок тексту. Знайти усі знаки пунктуації, які були використано.
  3. Дано рядок тексту. Вивести усі складові, які розділені розділовими знаками.
  4. Дано рядок тексту. Перевірити, чи містить він дату у форматі dd.mm.yyyy (dd- день, mm- місяць, yyyy- рік).
  5. Дано рядок тексту. Підрахувати кількість двоцифрових чисел у рядку.
  6. Визначити чи може бути рядок тексту номером банківської картки (приклад: «4142-3433-2323-3434»). Знайти усі такі номери.
  7. Дано адресу сайту. Визначити, чи є він урядовим (містить домен “gov”).
  8. Вибрати усі роки після 2021 року з отриманого повідомлення.
  9. Дано номер телефону. Перевірити, чи є цей телефон телефоном з України (починається на «+38»).
  10. Користувач вводить прізвище та ім’я в одному рядку через пробіл. Замінити пробіл на дефіс.
  11. Користувач вводить дату у форматі «день.місяць.рік». Отримати рядкове представлення дати у форматі «день/місяць/рік».
  12. Користувач вводить день (номер дня (0-6) або «sun,mon,tue,wed,thu,fri,sat»). Визначити, чи є цей день вихідним.

Рішення:

'use strict'

class TextFilterWidget {
  filteringFn
  cssSelector
  label
  options
  inputEl
  outputEl
  $el

  /**
   * @param {(input: string) => any} filteringFn
   * @param {string} cssSelector
   * @param {string} label
   * @param {Object} [options]
   */
  constructor(filteringFn, label, cssSelector = '.js-app', options = {}) {
    this.filteringFn = filteringFn
    this.cssSelector = cssSelector
    this.label = label
    this.options = {
      widgetClass:
        'u-flex-auto u-flex u-flex-col u-gap-300 u-p-400 u-rounded-lg u-border-zinc-700 u-is-xs',
      headerClass: 'u-flex-auto u-text-center u-font-bolder u-text-350',
      listClass: 'u-flow-200',
      itemClass: 'u-flow-100',
      labelClass: 'u-font-bolder',
      inputClass: 'c-input | u-min-bs-1600 u-max-bs-4000',
      outputClass: 'u-block u-min-bs-700',
      ...options,
    }
    this.render()
  }

  renderInput() {
    /** @type {HTMLTextAreaElement} */
    const inputEl = document.createElement('TEXTAREA')
    inputEl.className = this.options.inputClass
    inputEl.addEventListener('input', this.handleSearch.bind(this))

    return inputEl
  }

  renderField() {
    const uniqueId = crypto.randomUUID()

    const inputEl = this.renderInput()
    inputEl.id = uniqueId

    const labelEl = document.createElement('LABEL')
    labelEl.textContent = 'Вхідні дані'
    labelEl.className = this.options.labelClass
    labelEl.setAttribute('for', uniqueId)

    return {labelEl, inputEl}
  }

  formatInput(input) {
    if (input instanceof Array) return input.join('')
    if (!input) return 'немає збігів'

    return input
  }

  handleSearch() {
    const input = this.inputEl.value
    const result = this.filteringFn(input)

    this.outputEl.textContent = this.formatInput(result)
  }

  renderOutput() {
    const outputEl = document.createElement('OUTPUT')
    outputEl.className = this.options.outputClass

    return outputEl
  }

  renderItem() {
    const liEl = document.createElement('LI')
    liEl.className = this.options.itemClass

    for (const item of arguments) {
      liEl.append(item)
    }

    return liEl
  }

  renderWidget() {
    const headerEl = document.createElement('H3')
    headerEl.className = this.options.headerClass
    headerEl.textContent = this.label

    const {labelEl, inputEl} = this.renderField()

    const fieldLiEl = this.renderItem(labelEl, inputEl)

    const outputLabelEl = document.createElement('P')
    outputLabelEl.className = this.options.labelClass
    outputLabelEl.textContent = 'Вихідні дані'

    const outputEl = this.renderOutput()

    const outputLiEl = this.renderItem(outputLabelEl, outputEl)

    const listEl = document.createElement('UL')
    listEl.className = this.options.listClass
    listEl.append(fieldLiEl, outputLiEl)

    const widgetEl = document.createElement('ARTICLE')
    widgetEl.className = this.options.widgetClass
    widgetEl.append(headerEl, listEl)

    return {widgetEl, inputEl, outputEl}
  }

  render() {
    const elements = this.renderWidget()
    this.$el = elements.widgetEl
    this.inputEl = elements.inputEl
    this.outputEl = elements.outputEl

    document.querySelector(this.cssSelector).append(this.$el)
  }
}

// =============================================================================

// 6. Дано рядок тексту, вивести усі числа, які є у тексті.
new TextFilterWidget((t) => t.match(/[-+]?\b\d+(\.\d+)?\b/g), '6. Усі числа')

// 7. Дано рядок тексту. Знайти усі знаки пунктуації, які були використано.
const punctuationMarksRegExp = /[.,;:!?()[\]{}'"«»\-–—]/g
new TextFilterWidget(
  (t) => t.match(punctuationMarksRegExp),
  '7. Знаки пунктуації',
)

// 8. Дано рядок тексту. Вивести усі складові, які розділені розділовими знаками.
new TextFilterWidget(
  (t) => t.split(punctuationMarksRegExp).filter(Boolean),
  '8. Між розділовими знаками',
)

// 9. Дано рядок тексту. Перевірити, чи містить він дату у форматі dd.mm.yyyy (dd- день, mm- місяць, yyyy- рік).
new TextFilterWidget(
  (t) =>
    /\b(0?[1-9]|[12]\d|3[01])\.(0?[1-9]|1[0-2])\.\d{4}\b/.test(t) && 'містить',
  '9. Містить дату у форматі dd.mm.yyyy',
)

// 10. Дано рядок тексту. Підрахувати кількість двоцифрових чисел у рядку.
new TextFilterWidget(
  (t) => t.match(/(?<!\d|\d\.)\d{2}(?!\d|\.\d)/g)?.length,
  '10. Кількість двоцифрових чисел',
)

// 11. Визначити чи може бути рядок тексту номером банківської картки (приклад: «4142-3433-2323-3434»). Знайти усі такі номери.
new TextFilterWidget(
  (t) => t.match(/\b\d{4}( |-)?(?:\d{4}\1){2}\d{4}\b/g),
  '11. Банківські номери',
)

// 12. Дано адресу сайту. Визначити, чи є він урядовим (містить домен “gov”).
new TextFilterWidget(
  (t) => /\.gov\b/i.test(t) && 'урядовий',
  '12. Урядовий сайт',
)

// 13. Вибрати усі роки після 2021 року з отриманого повідомлення.
new TextFilterWidget(
  (t) => t.match(/\b(202[2-9]|20[3-9]\d|2[1-9]\d{2}|[3-9]\d{3})\b/g),
  '13. Роки після 2021',
)

// 14. Дано номер телефону. Перевірити, чи є цей телефон телефоном з України (починається на «+38»).
new TextFilterWidget(
  (t) =>
    /^\+38[ -]?\(?0\d{2}\)?[ -]?\d{3}[ -]?\d{2}[ -]?\d{2}$/.test(t) &&
    'з України',
  '14. Український номер телефону',
)

// 15. Користувач вводить прізвище та ім’я в одному рядку через пробіл. Замінити пробіл на дефіс.
new TextFilterWidget((t) => t.replaceAll(' ', ''), '15. Пробіл на дефіс')

// 16. Користувач вводить дату у форматі «день.місяць.рік». Отримати рядкове представлення дати у форматі «день/місяць/рік».
new TextFilterWidget(
  (t) =>
    t.replace(
      /\b(?<day>0?[1-9]|[12]\d|3[01])\.(?<month>0?[1-9]|1[0-2])\.(?<year>\d{4})\b/g,
      '$<day>/$<month>/$<year>',
    ),
  '16. день/місяць/рік',
)

// 17. Користувач вводить день (номер дня (0-6) або «sun,mon,tue,wed,thu,fri,sat»). Визначити, чи є цей день вихідним.
new TextFilterWidget(
  (t) => /\b(0|6|sun|sat)\b/g.test(t) && 'вихідний',
  '17. Чи вихідний',
)