Attribute VB_Name = "z_ParserRegex"
' ======== Parser regex masks ========
' Shared module version: 20210909
' Tested in:
' Depends on:
' Required reference:
Option Private Module
Option Explicit

Private Const P_SPACE = "(?:\s+?)"

Private Const P_QUOTE_OPEN = "[""'«“]"
Private Const P_QUOTE_CLOSE = "[""'»”]"
Private Const P_ANY_SHORTEST = ".*?"
Private Const P_ANY = ".*"

Private Const P_MONTH_RUS = "(?:января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)"
Private Const P_MONTH_DIGITS = "[0-1]?\d"
Private Const P_DAY_DIGITS = "[0-3]?\d"
Private Const P_YEAR_LONG = "[1-2]\d\d\d"
Private Const P_YEAR_SHORT = "\d\d"
Private Const P_YEAR_DIGITS = "(?:" & P_YEAR_LONG & "|" & P_YEAR_SHORT & ")"
  
Private Const P_DATE_TEXT = _
  "(" & P_DAY_DIGITS & ")" & P_SPACE & _
  "(" & P_MONTH_RUS & ")" & P_SPACE & _
  "(" & P_YEAR_LONG & ")"
  
Private Const P_DATE_NUMERIC = _
  "(" & P_DAY_DIGITS & ")" & "\." & _
  "(" & P_MONTH_DIGITS & ")" & "\." & _
  "(" & P_YEAR_DIGITS & ")"
  
Private Const P_NPA_PREFIX = "[А-Яа-я][\dА-Яа-яA-Za-z,\-\.""'«»“”\s]+?"
Private Const P_NPA_ID_ELEMENT = "[#N№]" & P_SPACE & "?" & "[\dА-Яа-яA-Za-z_@\.\-\\/]+"
Private Const P_NPA_ID_SEQ = P_NPA_ID_ELEMENT & "(?:," & P_SPACE & P_NPA_ID_ELEMENT & ")*"
Private Const P_NPA_INTRO = _
  "(?:" & _
    "[Пп]риложение к" & "|" & _
    "[Вв] редакции" & "|" & _
    "(?:" & _
      "[Рр]екомендован[аоы]?" & "|" & _
      "(?:" & _
        "[Уу]тв\." & "|" & _
        "[Уу]твержд(?:[её]н|ена|ено|ены)" & _
      ")" & " и введ(?:[её]н|ена|ено|ены) в действие" & "|" & _
      "(?:принят[аоы]? и )?" & _
      "(?:" & _
        "[Уу]тв\." & "|" & _
        "[Уу]твержд(?:[её]н|ена|ено|ены)" & "|" & _
        "одобрен[аоы]?" & "|" & _
        "[Вв]вед(?:[её]н|ена|ено|ены) в действие" & _
      ")" & "|" & _
      "принят[аоы]?" & _
    ")" & "(?: на)?" & _
  ")"

Private Const P_MASK_DOCTYPE = _
  "(?:" & _
    "[Кк]онституаци[яи]" & "|" & _
    "[Фф]едеральн(?:ый|ым|ого|ому) закон(?:ом|а|у)?" & "|" & _
    "[Фф]едеральн(?:ый|ым|ого|ому) [Кк]онституционн(?:ый|ым|ого|ому)] закон(?:ом|а|у)?" & "|" & _
    "[Зз]акон(?:ом|а|у)?(?: РФ| Российской Федерации)?" & "|" & _
    "[Дд]иректив(?:а|ой|ы|е)" & "|" & _
    P_ANY & "[Кк]одекс(?:ом)?" & P_ANY & "|" & _
    P_ANY & "[Кк]онвенци(?:я|ей|ии)" & "|" & _
    "[Уу]казани(?:ем|е|я|ю)" & "|" & _
    "[Зз]аключени(?:ем|е|я|ю)" & "|" & _
    "[Пп]исьм(?:ом|о|а|у)" & "|" & _
    "[Рр]азъяснени(?:ем|е|я|ю)" & "|" & _
    "[Пп]остановлени(?:ем|е|я|ю)" & "|" & _
    "[Пп]риказ(?:ом|а|у)?" & "|" & _
    "[Уу]каз(?:ом|а|у)?" & "|" & _
    "[Ии]нформационн(?:ое|ым|ого|ому) письм(?:ом|о|а|у)" & "|" & _
    "[Рр]аспоряжени(?:ем|е|я|ю)" & "|" & _
    "[Сс]оглашени(?:ем|е|я|ю)(?: о взаимодействии)?" & "|" & _
    "[Рр]ешени(?:ем|е|я|ю)" & _
  ")"

Private Const P_NPA_TITLE_PREFIX = _
  "(?:" & _
    "[Оо] введении в действие" & "(?: новой редакции)?" & "|" & _
    "[Оо]б издании и применении" & "|" & _
    "[Оо]б утверждении(?: и(?: о)? введении в действие)?" & _
  " " & _
  ")"

' ======================================
' ======== Итоговые выражения ==========
' ======================================

' ======= Дата ==========
Public Const P_DATE_NO_CAPTURE = _
  "(?:" & _
    P_DAY_DIGITS & P_SPACE & P_MONTH_RUS & P_SPACE & P_YEAR_LONG & _
    "|" & _
    P_DAY_DIGITS & "\." & P_MONTH_DIGITS & "\." & P_YEAR_DIGITS & _
  ")" & _
  "(?:" & P_SPACE & "?" & "(?:года|г\.|г))?"
  
Public Const P_DATE_CAPTURE = _
  "^" & _
    "(?:" & _
      P_DATE_TEXT & "|" & _
      P_DATE_NUMERIC & _
    ")" & _
    "(?:" & P_SPACE & "?" & "(?:года|г\.|г))?" & _
  "$"
  
' ====== Название НПА ======
Public Const P_NPA_SCAN = _
  "(?:" & "\b[Сс]м\." & P_SPACE & ")?" & _
  "(?:" & _
      "\bв редакции " & "|" & _
      "\bв соответствии с " & _
  ")?" & _
  "(" & _
    P_NPA_PREFIX & P_SPACE & "от" & P_SPACE & P_DATE_NO_CAPTURE & P_SPACE & "?" & _
    P_NPA_ID_SEQ & "(?:" & P_SPACE & P_QUOTE_OPEN & P_ANY & P_QUOTE_CLOSE & ")?" & _
    "|" & _
    P_ANY_SHORTEST & _
    "\(" & _
      P_ANY_SHORTEST & P_NPA_INTRO & P_SPACE & P_NPA_PREFIX & _
      "(?:" & P_SPACE & "от" & ")?" & P_SPACE & P_DATE_NO_CAPTURE & _
      "(?:" & P_SPACE & "?" & "(?:" & P_NPA_ID_SEQ & "))?" & P_ANY_SHORTEST & _
    "\)" & _
  ")"

Public Const P_NPA_PROPS_FIRST = _
  "^" & _
    "(" & P_NPA_PREFIX & ")" & _
    P_SPACE & "от" & P_SPACE & "(" & P_DATE_NO_CAPTURE & ")" & _
    P_SPACE & "?" & "(" & P_NPA_ID_SEQ & ")" & _
    "(?:" & P_SPACE & P_QUOTE_OPEN & "(" & P_ANY & ")" & P_QUOTE_CLOSE & ")?" & _
    P_ANY_SHORTEST & _
  "$"

Public Const P_NPA_TITLE_FIRST = _
  "^" & _
    "(" & P_ANY_SHORTEST & ")" & _
    "\(" & _
      P_ANY_SHORTEST & P_NPA_INTRO & P_SPACE & _
      "(" & P_NPA_PREFIX & ")" & P_SPACE & _
      "(?:от" & P_SPACE & ")?" & "(" & P_DATE_NO_CAPTURE & ")" & _
      "(?:" & P_SPACE & "?" & "(" & P_NPA_ID_SEQ & "))?" & _
      P_ANY_SHORTEST & _
    "\)" & _
    P_ANY_SHORTEST & _
  "$"
  
' ===== Тип документа =========
Public Const P_NPA_DOCTYPE = "^" & "(" & P_MASK_DOCTYPE & ")"

' ======== Титул документа ======
Public Const P_NPA_COMPOSITE_TITLE = _
  "^" & _
    "(" & P_NPA_TITLE_PREFIX & ")" & _
    P_QUOTE_OPEN & "?" & _
    "(" & P_ANY_SHORTEST & ")" & _
    P_QUOTE_CLOSE & "?" & _
  "$"

' ======== Срочность документа ===
Public Const P_NPA_IMMEDIATE = _
  " " & _
  "(?:(?:с|на|в|до) |\()" & _
  "(?:плановый |период |плановый период )?" & _
  P_YEAR_DIGITS & _
  "(?:" & _
    "(?:\-| \- | и | по )" & _
    P_YEAR_DIGITS & _
  ")?" & _
  " " & _
  "(?:год(?:ов|а|ы|ах)?|гг\.|гг|г\.|г)"

' ======== Static access for compiled regexp ======
Public Function GlobalDateRegex() As RegExp
  Static s_Regex As RegExp
  If s_Regex Is Nothing Then
    Set s_Regex = New RegExp
    s_Regex.Global = True
    s_Regex.Pattern = P_DATE_NO_CAPTURE
  End If
  Set GlobalDateRegex = s_Regex
End Function

Public Function GlobalNPARegex() As RegExp
  Static s_Regex As RegExp
  If s_Regex Is Nothing Then
    Set s_Regex = New RegExp
    s_Regex.Global = True
    s_Regex.Pattern = P_NPA_SCAN
  End If
  Set GlobalNPARegex = s_Regex
End Function

' ============= Типы документов-определений
' Положен(?:ия|ие|ии) об?
' Поряд(?:ка|ок|ке)
' Правила?
' (?:Административного)?[Рр]егламента?(?: по)?
' Рекомендаци[ий] по
' Стратеги[ия]
' Структур[аы]
' Типово(?:го|ое) положени[яе] об?
' Требований(?:(?:, предъявляемых)? к)?
' Форм[аы]? и порядка
' Форм[аы]?
' Перечень

' ============ Типы документов-действий
' О внесении изменений в
' О(?: некоторых| неотложных| первоочередных)? мерах по (?:реализации|стимулированию|совершенствованию)
' О мероприятиях по
' О перечне
' О подготовке проекта
' О (подписании|принятии|ратификации)
' О реализации
' О создании(?: и ведении)?
' Об изменении состава
' Об образовании ' чего-либо
' Об объявлении ' Другого документа
' Об организации(?: работы? по)?
' Об осуществлении
' Об усилении ' = cовершенствование?
' Об установлении ' задание значения
' Об определении ' процедура задания значения

' ========= TODO
' Парсить выделяя органы-акторы
' Private Const P_ANY_SPECIAL_SPACE = "[ \xA0\u1680\u180E\u2000-\u200B\u202F\u205F\u3000\uFEFF]+"

