VBCommons/parsers/z_ParserRegex.bas

233 lines
7.0 KiB
QBasic
Raw Permalink Normal View History

2024-06-07 20:46:40 +03:00
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 = "[""'<27><>]"
Private Const P_QUOTE_CLOSE = "[""'<27><>]"
Private Const P_ANY_SHORTEST = ".*?"
Private Const P_ANY = ".*"
Private Const P_MONTH_RUS = "(?:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)"
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 = "[<5B>-<2D><>-<2D>][\d<>-<2D><>-<2D>A-Za-z,\-\.""'<27><><EFBFBD><EFBFBD>\s]+?"
Private Const P_NPA_ID_ELEMENT = "[#N<>]" & P_SPACE & "?" & "[\d<>-<2D><>-<2D>A-Za-z_@\.\-\\/]+"
Private Const P_NPA_ID_SEQ = P_NPA_ID_ELEMENT & "(?:," & P_SPACE & P_NPA_ID_ELEMENT & ")*"
Private Const P_NPA_INTRO = _
"(?:" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>" & "|" & _
"[<5B><>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" & "|" & _
"(?:" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>]?" & "|" & _
"(?:" & _
"[<5B><>]<5D><>\." & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:[<5B><>]<5D>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>)" & _
")" & " <20> <20><><EFBFBD><EFBFBD>(?:[<5B><>]<5D>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>) <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" & "|" & _
"(?:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>]? <20> )?" & _
"(?:" & _
"[<5B><>]<5D><>\." & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:[<5B><>]<5D>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>)" & "|" & _
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>]?" & "|" & _
"[<5B><>]<5D><><EFBFBD>(?:[<5B><>]<5D>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>) <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" & _
")" & "|" & _
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>]?" & _
")" & "(?: <20><>)?" & _
")"
Private Const P_MASK_DOCTYPE = _
"(?:" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><>]" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>|<7C><><EFBFBD>|<7C><><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>)?" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>|<7C><><EFBFBD>|<7C><><EFBFBD>) [<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>|<7C><><EFBFBD>|<7C><><EFBFBD>)] <20><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>)?" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>)?(?: <20><>| <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)?" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A>|<7C><>|<7C>|<7C>)" & "|" & _
P_ANY & "[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>)?" & P_ANY & "|" & _
P_ANY & "[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A>|<7C><>|<7C><>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>)?" & "|" & _
"[<5B><>]<5D><><EFBFBD>(?:<3A><>|<7C>|<7C>)?" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>|<7C><><EFBFBD>|<7C><><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)(?: <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)?" & "|" & _
"[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C>)" & _
")"
Private Const P_NPA_TITLE_PREFIX = _
"(?:" & _
"[<5B><>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" & "(?: <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)?" & "|" & _
"[<5B><>]<5D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" & "|" & _
"[<5B><>]<5D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?: <20>(?: <20>)? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)?" & _
" " & _
")"
' ======================================
' ======== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==========
' ======================================
' ======= <20><><EFBFBD><EFBFBD> ==========
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 & "?" & "(?:<3A><><EFBFBD><EFBFBD>|<7C>\.|<7C>))?"
Public Const P_DATE_CAPTURE = _
"^" & _
"(?:" & _
P_DATE_TEXT & "|" & _
P_DATE_NUMERIC & _
")" & _
"(?:" & P_SPACE & "?" & "(?:<3A><><EFBFBD><EFBFBD>|<7C>\.|<7C>))?" & _
"$"
' ====== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> ======
Public Const P_NPA_SCAN = _
"(?:" & "\b[<5B><>]<5D>\." & P_SPACE & ")?" & _
"(?:" & _
"\b<> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " & "|" & _
"\b<> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> " & _
")?" & _
"(" & _
P_NPA_PREFIX & P_SPACE & "<22><>" & 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 & "<22><>" & ")?" & 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 & "<22><>" & 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 & _
"(?:<3A><>" & P_SPACE & ")?" & "(" & P_DATE_NO_CAPTURE & ")" & _
"(?:" & P_SPACE & "?" & "(" & P_NPA_ID_SEQ & "))?" & _
P_ANY_SHORTEST & _
"\)" & _
P_ANY_SHORTEST & _
"$"
' ===== <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> =========
Public Const P_NPA_DOCTYPE = "^" & "(" & P_MASK_DOCTYPE & ")"
' ======== <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ======
Public Const P_NPA_COMPOSITE_TITLE = _
"^" & _
"(" & P_NPA_TITLE_PREFIX & ")" & _
P_QUOTE_OPEN & "?" & _
"(" & P_ANY_SHORTEST & ")" & _
P_QUOTE_CLOSE & "?" & _
"$"
' ======== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ===
Public Const P_NPA_IMMEDIATE = _
" " & _
"(?:(?:<3A>|<7C><>|<7C>|<7C><>) |\()" & _
"(?:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> )?" & _
P_YEAR_DIGITS & _
"(?:" & _
"(?:\-| \- | <20> | <20><> )" & _
P_YEAR_DIGITS & _
")?" & _
" " & _
"(?:<3A><><EFBFBD>(?:<3A><>|<7C>|<7C>|<7C><>)?|<7C><>\.|<7C><>|<7C>\.|<7C>)"
' ======== 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
' ============= <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>|<7C><>) <20><>?
' <20><><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>|<7C><>)
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
' (?:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)?[<5B><>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?(?: <20><>)?
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><>] <20><>
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><>]
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><>]
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:<3A><>|<7C><>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><>] <20><>?
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?:(?:, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)? <20>)?
' <20><><EFBFBD><EFBFBD>[<5B><>]? <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20><><EFBFBD><EFBFBD>[<5B><>]?
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' ============ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
' <20>(?: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>| <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>| <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)? <20><><EFBFBD><EFBFBD><EFBFBD> <20><> (?:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
' <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
' <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
' <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?: <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)?
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ' <20><><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD>
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(?: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20><>)?
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ' = c<><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' ========= TODO
' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
' Private Const P_ANY_SPECIAL_SPACE = "[ \xA0\u1680\u180E\u2000-\u200B\u202F\u205F\u3000\uFEFF]+"