1 <?xml version=
"1.0" encoding=
"UTF-8"?>
2 <!DOCTYPE script:module PUBLIC
"-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
3 <script:module xmlns:
script=
"http://openoffice.org/2000/script" script:
name=
"SF_String" script:
language=
"StarBasic" script:
moduleType=
"normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === Full documentation is available on https://help.libreoffice.org/ ===
6 REM =======================================================================================================================
11 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
12 ''' SF_String
13 ''' =========
14 ''' Singleton class implementing the
"ScriptForge.String
" service
15 ''' Implemented as a usual Basic module
16 ''' Focus on string manipulation, regular expressions, encodings and hashing algorithms
17 ''' The first argument of almost every method is the string to consider
18 ''' It is always passed by reference and left unchanged
19 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
20 ''' Definitions
21 ''' Line breaks: symbolic name(Ascii number)
22 ''' LF(
10), VT(
12), CR(
13), LF+CR, File separator(
28), Group separator(
29), Record separator(
30),
23 ''' Next Line(
133), Line separator(
8232), Paragraph separator(
8233)
24 ''' Whitespaces: symbolic name(Ascii number)
25 ''' Space(
32), HT(
9), LF(
10), VT(
11), FF(
12), CR(
13), Next Line(
133), No-break space(
160),
26 ''' Line separator(
8232), Paragraph separator(
8233)
27 ''' A quoted string:
28 ''' The quoting character must be the double quote (
")
29 ''' To preserve a quoting character inside the quoted substring, use (\) or (
") as escape character
30 ''' =
> [str\
"i
""ng] means [str
"i
"ng]
31 ''' Escape sequences: symbolic name(Ascii number) = escape sequence
32 ''' Line feed(
10) =
"\n
"
33 ''' Carriage return(
13) =
"\r
"
34 ''' Horizontal tab(
9) =
"\t
"
35 ''' Double the backslash to ignore the sequence, e.g.
"\\n
" means
"\n
" (not
"\
" & Chr(
10)).
36 ''' Not printable characters:
37 ''' Defined in the Unicode character database as “Other” or “Separator”
38 ''' In particular,
"control
" characters (ascii code
<=
0x1F) are not printable
40 ''' Detailed user documentation:
41 ''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/
03/sf_string.html?DbPAR=BASIC
42 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
43 ''' Some references:
44 ''' https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1i18n_1_1KCharacterType.html
45 ''' com.sun.star.i18n.KCharacterType.###
46 ''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1i18n_1_1XCharacterClassification.html
47 ''' com.sun.star.i18n.XCharacterClassification
49 REM ============================================================ MODULE CONSTANTS
51 ''' Most expressions below are derived from https://www.regular-expressions.info/
53 Const REGEXALPHA =
"^[A-Za-z]+$
" ' Not used
54 Const REGEXALPHANUM =
"^[\w]+$
"
55 Const REGEXDATEDAY =
"(
0[
1-
9]|[
12][
0-
9]|
3[
01])
"
56 Const REGEXDATEMONTH =
"(
0[
1-
9]|
1[
012])
"
57 Const REGEXDATEYEAR =
"(
19|
20)\d\d
"
58 Const REGEXTIMEHOUR =
"(
0[
1-
9]|
1[
0-
9]|
2[
0123])
"
59 Const REGEXTIMEMIN =
"([
0-
5][
0-
9])
"
60 Const REGEXTIMESEC = REGEXTIMEMIN
61 Const REGEXDIGITS =
"^[
0-
9]+$
"
62 Const REGEXEMAIL =
"^[A-Z0-
9._%+-]+@[A-Z0-
9.-]+\.[A-Z]{
2,}$
"
63 Const REGEXFILELINUX =
"^[^
<>:;,?
""*|\\]+$
"
64 Const REGEXFILEWIN =
"^([A-Z]|[a-z]:)?[^
<>:;,?
""*|]+$
"
65 Const REGEXHEXA =
"^(
0X|
&H)?[
0-
9A-F]+$
" ' Includes
0xFF and
&HFF
66 Const REGEXIPV4 =
"^(?:(?:
25[
0-
5]|
2[
0-
4][
0-
9]|[
01]?[
0-
9][
0-
9]?)\.){
3}(?:
25[
0-
5]|
2[
0-
4][
0-
9]|[
01]?[
0-
9][
0-
9]?)$
"
67 Const REGEXNUMBER =
"^[-+]?(([
0-
9]+)?\.)?[
0-
9]+([eE][-+]?[
0-
9]+)?$
"
68 Const REGEXURL =
"^(https?|ftp)://[^\s/$.?#].[^\s]*$
"
69 Const REGEXWHITESPACES =
"^[\s]+$
"
70 Const REGEXLTRIM =
"^[\s]+
"
71 Const REGEXRTRIM =
"[\s]+$
"
72 Const REGEXSPACES =
"[\s]+
"
74 ''' Accented characters substitution: https://docs.google.com/spreadsheets/d/
1pJKSueZK8RkAcJFQIiKpYUamWSC1u1xVQchK7Z7BIwc/edit#gid=
0
75 ''' (Many of them are in the list, but do not consider the list as closed vs. the Unicode database)
77 Const cstCHARSWITHACCENT =
"ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðñòóôõöùúûüýÿŠšŸŽž
" _
78 & "ĂăĐđĨĩŨũƠơƯưẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹ₫
"
79 Const cstCHARSWITHOUTACCENT =
"AAAAAACEEEEIIIIDNOOOOOUUUUYaaaaaaceeeeiiiidnooooouuuuyySsYZz
" _
80 & "AaDdIiUuOoUuAaAaAaAaAaAaAaAaAaAaAaAaEeEeEeEeEeEeEeEeIiIiOoOoOoOoOoOoOoOoOoOoOoOoUuUuUuUuUuUuUuYyYyYyYyd
"
82 REM ===================================================== CONSTRUCTOR/DESTRUCTOR
84 REM -----------------------------------------------------------------------------
85 Public Function Dispose() As Variant
87 End Function
' ScriptForge.SF_String Explicit destructor
89 REM ================================================================== PROPERTIES
91 REM -----------------------------------------------------------------------------
92 Property Get CHARSWITHACCENT() As String
93 ''' Latin accents
94 CHARSWITHACCENT = cstCHARSWITHACCENT
95 End Property
' ScriptForge.SF_String.CHARSWITHACCENT
97 REM -----------------------------------------------------------------------------
98 Property Get CHARSWITHOUTACCENT() As String
99 ''' Latin accents
100 CHARSWITHOUTACCENT = cstCHARSWITHOUTACCENT
101 End Property
' ScriptForge.SF_String.CHARSWITHOUTACCENT
103 ''' Symbolic constants for linebreaks
104 REM -----------------------------------------------------------------------------
105 Property Get sfCR() As Variant
106 ''' Carriage return
108 End Property
' ScriptForge.SF_String.sfCR
110 REM -----------------------------------------------------------------------------
111 Property Get sfCRLF() As Variant
112 ''' Carriage return
113 sfCRLF = Chr(
13)
& Chr(
10)
114 End Property
' ScriptForge.SF_String.sfCRLF
116 REM -----------------------------------------------------------------------------
117 Property Get sfLF() As Variant
118 ''' Linefeed
120 End Property
' ScriptForge.SF_String.sfLF
122 REM -----------------------------------------------------------------------------
123 Property Get sfNEWLINE() As Variant
124 ''' Linefeed or Carriage return + Linefeed
125 sfNEWLINE = Iif(GetGuiType() =
1, Chr(
13),
"")
& Chr(
10)
126 End Property
' ScriptForge.SF_String.sfNEWLINE
128 REM -----------------------------------------------------------------------------
129 Property Get sfTAB() As Variant
130 ''' Horizontal tabulation
132 End Property
' ScriptForge.SF_String.sfTAB
134 REM -----------------------------------------------------------------------------
135 Property Get ObjectType As String
136 ''' Only to enable object representation
137 ObjectType =
"SF_String
"
138 End Property
' ScriptForge.SF_String.ObjectType
140 REM -----------------------------------------------------------------------------
141 Property Get ServiceName As String
142 ''' Internal use
143 ServiceName =
"ScriptForge.String
"
144 End Property
' ScriptForge.SF_String.ServiceName
146 REM ============================================================== PUBLIC METHODS
148 REM -----------------------------------------------------------------------------
149 Public Function Capitalize(Optional ByRef InputStr As Variant) As String
150 ''' Return the input string with the
1st character of each word in title case
151 ''' Args:
152 ''' InputStr: the input string
153 ''' Returns:
154 ''' The input string with the
1st character of each word in title case
155 ''' Examples:
156 ''' SF_String.Capitalize(
"this is a title for jean-pierre
") returns
"This Is A Title For Jean-Pierre
"
158 Dim sCapital As String
' Return value
159 Dim lLength As Long
' Length of input string
160 Dim oLocale As Object
' com.sun.star.lang.Locale
161 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
162 Const cstThisSub =
"String.Capitalize
"
163 Const cstSubArgs =
"InputStr
"
165 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
166 sCapital =
""
169 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
170 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
174 lLength = Len(InputStr)
175 If lLength
> 0 Then
176 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
177 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
178 sCapital = oChar.toTitle(InputStr,
0, lLength *
4, oLocale)
' length *
4 because length is expressed in bytes
182 Capitalize = sCapital
183 SF_Utils._ExitFunction(cstThisSub)
187 End Function
' ScriptForge.SF_String.Capitalize
189 REM -----------------------------------------------------------------------------
190 Public Function Count(Optional ByRef InputStr As Variant _
191 , Optional ByVal Substring As Variant _
192 , Optional ByRef IsRegex As Variant _
193 , Optional ByVal CaseSensitive As Variant _
195 ''' Counts the number of occurrences of a substring or a regular expression within a string
196 ''' Args:
197 ''' InputStr: the input stringto examine
198 ''' Substring: the substring to identify
199 ''' IsRegex: True if Substring is a regular expression (default = False)
200 ''' CaseSensitive: default = False
201 ''' Returns:
202 ''' The number of occurrences as a Long
203 ''' Examples:
204 ''' SF_String.Count(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"\b[a-z]+\b
", IsRegex := True, CaseSensitive := True)
205 ''' returns
7 (the number of words in lower case)
206 ''' SF_String.Count(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"or
", CaseSensitive := False)
207 ''' returns
2
210 Dim lOccurrences As Long
' Return value
211 Dim lStart As Long
' Start index of search
212 Dim sSubstring As String
' Substring to replace
213 Dim iCaseSensitive As Integer
' Integer alias for boolean CaseSensitive
214 Const cstThisSub =
"String.Count
"
215 Const cstSubArgs =
"InputStr, Substring, [IsRegex=False], [CaseSensitive=False]
"
217 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
221 If IsMissing(IsRegex) Or IsEmpty(IsRegex) Then IsRegex = False
222 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
223 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
224 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
225 If Not SF_Utils._Validate(Substring,
"Substring
", V_STRING) Then GoTo Finally
226 If Not SF_Utils._Validate(IsRegex,
"IsRegex
", V_BOOLEAN) Then GoTo Finally
227 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
231 iCaseSensitive = Iif(CaseSensitive,
0,
1)
' 1 = False ;)
234 Do While lStart
>=
1 And lStart
<= Len(InputStr)
236 Case False
' Use InStr
237 lStart = InStr(lStart, InputStr, Substring, iCaseSensitive)
238 If lStart =
0 Then Exit Do
239 lStart = lStart + Len(Substring)
240 Case True
' Use FindRegex
241 sSubstring = SF_String.FindRegex(InputStr, Substring, lStart, CaseSensitive)
242 If lStart =
0 Then Exit Do
243 lStart = lStart + Len(sSubstring)
245 lOccurrences = lOccurrences +
1
250 SF_Utils._ExitFunction(cstThisSub)
254 End Function
' ScriptForge.SF_String.Count
256 REM -----------------------------------------------------------------------------
257 Public Function EndsWith(Optional ByRef InputStr As Variant _
258 , Optional ByVal Substring As Variant _
259 , Optional ByVal CaseSensitive As Variant _
261 ''' Returns True if the last characters of InputStr are identical to Substring
262 ''' Args:
263 ''' InputStr: the input string
264 ''' Substring: the suffixing characters
265 ''' CaseSensitive: default = False
266 ''' Returns:
267 ''' True if the comparison is satisfactory
268 ''' False if either InputStr or Substring have a length =
0
269 ''' False if Substr is longer than InputStr
270 ''' Examples:
271 ''' SF_String.EndsWith(
"abcdefg
",
"EFG
") returns True
272 ''' SF_String.EndsWith(
"abcdefg
",
"EFG
", CaseSensitive := True) returns False
274 Dim bEndsWith As Boolean
' Return value
275 Dim lSub As Long
' Length of SUbstring
276 Const cstThisSub =
"String.EndsWith
"
277 Const cstSubArgs =
"InputStr, Substring, [CaseSensitive=False]
"
279 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
283 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
284 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
285 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
286 If Not SF_Utils._Validate(Substring,
"Substring
", V_STRING) Then GoTo Finally
287 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
291 lSub = Len(Substring)
292 If Len(InputStr)
> 0 And lSub
> 0 And lSub
<= Len(InputStr) Then
293 bEndsWith = ( StrComp(Right(InputStr, lSub), Substring, Iif(CaseSensitive,
1,
0)) =
0 )
298 SF_Utils._ExitFunction(cstThisSub)
302 End Function
' ScriptForge.SF_String.EndsWith
304 REM -----------------------------------------------------------------------------
305 Public Function Escape(Optional ByRef InputStr As Variant) As String
306 ''' Convert any hard line breaks or tabs by their escaped equivalent
307 ''' Args:
308 ''' InputStr: the input string
309 ''' Returns:
310 ''' The input string after replacement of
"\
", Chr(
10), Chr(
13), Chr(
9)characters
311 ''' Examples:
312 ''' SF_String.Escape(
"abc
" & Chr(
10)
& Chr(
9)
& "def\n
") returns
"abc\n\tdef\\n
"
314 Dim sEscape As String
' Return value
315 Const cstThisSub =
"String.Escape
"
316 Const cstSubArgs =
"InputStr
"
318 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
319 sEscape =
""
322 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
323 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
327 sEscape = SF_String.ReplaceStr( InputStr _
328 , Array(
"\
", SF_String.sfLF, SF_String.sfCR, SF_String.sfTAB) _
329 , Array(
"\\
",
"\n
",
"\r
",
"\t
") _
334 SF_Utils._ExitFunction(cstThisSub)
338 End Function
' ScriptForge.SF_String.Escape
340 REM -----------------------------------------------------------------------------
341 Public Function ExpandTabs(Optional ByRef InputStr As Variant _
342 , Optional ByVal TabSize As Variant _
344 ''' Return the input string with each TAB (Chr(
9)) character replaced by the adequate number of spaces
345 ''' Args:
346 ''' InputStr: the input string
347 ''' TabSize: defines the TAB positions at TabSize +
1,
2 * TabSize +
1 , ... N * TabSize +
1
348 ''' Default =
8
349 ''' Returns:
350 ''' The input string with spaces replacing the TAB characters
351 ''' If the input string contains line breaks, the TAB positions are reset
352 ''' Examples:
353 ''' SF_String.ExpandTabs(
"abc
" & SF_String.sfTAB
& SF_String.sfTAB
& "def
",
4) returns
"abc def
"
354 ''' SF_String.ExpandTabs(
"abc
" & SF_String.sfTAB
& "def
" & SF_String.sfLF
& SF_String.sfTAB
& "ghi
")
355 ''' returns
"abc def
" & SF_String.sfLF
& " ghi
"
357 Dim sExpanded As String
' Return value
358 Dim lCharPosition As Long
' Position of current character in current line in expanded string
359 Dim lSpaces As Long
' Spaces counter
360 Dim sChar As String
' A single character
363 Const cstThisSub =
"String.ExpandTabs
"
364 Const cstSubArgs =
"InputStr, [TabSize=
8]
"
366 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
367 sExpanded =
""
370 If IsMissing(TabSize) Or IsEmpty(TabSize) Then TabSize = cstTabSize
371 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
372 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
373 If Not SF_Utils._Validate(TabSize,
"TabSize
", V_NUMERIC) Then GoTo Finally
375 If TabSize
<=
0 Then TabSize = cstTabSize
379 If Len(InputStr)
> 0 Then
380 For i =
1 To Len(InputStr)
381 sChar = Mid(InputStr, i,
1)
383 Case SF_String.sfLF, Chr(
12), SF_String.sfCR, Chr(
28), Chr(
29), Chr(
30), Chr(
133), Chr(
8232), Chr(
8233)
384 sExpanded = sExpanded
& sChar
387 lSpaces = Int(lCharPosition / TabSize +
1) * TabSize - lCharPosition
388 sExpanded = sExpanded
& Space(lSpaces)
389 lCharPosition = lCharPosition + lSpaces
391 sExpanded = sExpanded
& sChar
392 lCharPosition = lCharPosition +
1
398 ExpandTabs = sExpanded
399 SF_Utils._ExitFunction(cstThisSub)
403 End Function
' ScriptForge.SF_String.ExpandTabs
405 REM -----------------------------------------------------------------------------
406 Public Function FilterNotPrintable(Optional ByRef InputStr As Variant _
407 , Optional ByVal ReplacedBy As Variant _
409 ''' Return the input string in which all the not printable characters are replaced by ReplacedBy
410 ''' Among others, control characters (Ascii
<=
1F) are not printable
411 ''' Args:
412 ''' InputStr: the input string
413 ''' ReplacedBy: zero, one or more characters replacing the found not printable characters
414 ''' Default = the zero-length string
415 ''' Returns:
416 ''' The input string in which all the not printable characters are replaced by ReplacedBy
417 ''' Examples:
418 ''' SF_String.FilterNotPrintable(
"àén ΣlPµ
" & Chr(
10)
& " Русский
",
"\n
") returns
"àén ΣlPµ\n Русский
"
420 Dim sPrintable As String
' Return value
421 Dim bPrintable As Boolean
' Is a single character printable ?
422 Dim lLength As Long
' Length of InputStr
423 Dim lReplace As Long
' Length of ReplacedBy
424 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
425 Dim oLocale As Object
' com.sun.star.lang.Locale
426 Dim lType As Long
' com.sun.star.i18n.KCharacterType
427 Dim sChar As String
' A single character
428 Dim lPRINTABLE As Long : lPRINTABLE = com.sun.star.i18n.KCharacterType.PRINTABLE
430 Const cstThisSub =
"String.FilterNotPrintable
"
431 Const cstSubArgs =
"InputStr, [ReplacedBy=
""""]
"
433 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
434 sPrintable =
""
437 If IsMissing(ReplacedBy) Or IsEmpty(ReplacedBy) Then ReplacedBy =
""
438 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
439 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
440 If Not SF_Utils._Validate(ReplacedBy,
"ReplacedBy
", V_STRING) Then GoTo Finally
444 lLength = Len(InputStr)
445 lReplace = Len(ReplacedBy)
446 If lLength
> 0 Then
447 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
448 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
449 For i =
0 To lLength -
1
450 sChar = Mid(InputStr, i +
1,
1)
451 lType = oChar.getCharacterType(sChar,
0, oLocale)
452 ' Parenthses (), [], {} have a KCharacterType =
0
453 bPrintable = ( (lType And lPRINTABLE) = lPRINTABLE Or (lType =
0 And Asc(sChar)
<=
127) )
454 If Not bPrintable Then
455 If lReplace
> 0 Then sPrintable = sPrintable
& ReplacedBy
457 sPrintable = sPrintable
& sChar
463 FilterNotPrintable = sPrintable
464 SF_Utils._ExitFunction(cstThisSub)
468 End Function
' ScriptForge.SF_String.FilterNotPrintable
470 REM -----------------------------------------------------------------------------
471 Public Function FindRegex(Optional ByRef InputStr As Variant _
472 , Optional ByVal Regex As Variant _
473 , Optional ByRef Start As Variant _
474 , Optional ByVal CaseSensitive As Variant _
475 , Optional ByVal Forward As Variant _
477 ''' Find in InputStr a substring matching a given regular expression
478 ''' Args:
479 ''' InputStr: the input string to be searched for the expression
480 ''' Regex: the regular expression
481 ''' Start (passed by reference): where to start searching from
482 ''' Should be =
1 (Forward = True) or = Len(InputStr) (Forward = False) the
1st time
483 ''' After execution points to the first character of the found substring
484 ''' CaseSensitive: default = False
485 ''' Forward: True (default) or False (backward)
486 ''' Returns:
487 ''' The found substring matching the regular expression
488 ''' A zero-length string if not found (Start is set to
0)
489 ''' Examples:
490 ''' Dim lStart As Long : lStart =
1
491 ''' SF_String.FindRegex(
"abCcdefghHij
",
"C.*H
", lStart, CaseSensitive := True) returns
"CcdefghH
"
492 ''' Above statement may be reexecuted for searching the same or another pattern
493 ''' by starting from lStart + Len(matching string)
495 Dim sOutput As String
' Return value
496 Dim oTextSearch As Object
' com.sun.star.util.TextSearch
497 Dim vOptions As Variant
' com.sun.star.util.SearchOptions
498 Dim lEnd As Long
' Upper limit of search area
499 Dim vResult As Object
' com.sun.star.util.SearchResult
500 Const cstThisSub =
"String.FindRegex
"
501 Const cstSubArgs =
"InputStr, Regex, [Start=
1], [CaseSensitive=False], [Forward=True]
"
503 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
504 sOutput =
""
507 If IsMissing(Start) Or IsEmpty(Start) Then Start =
1
508 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
509 If IsMissing(Forward) Or IsEmpty(Forward) Then Forward = True
510 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
511 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
512 If Not SF_Utils._Validate(Regex,
"Regex
", V_STRING) Then GoTo Finally
513 If Not SF_Utils._Validate(Start,
"Start
", V_NUMERIC) Then GoTo Finally
514 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
515 If Not SF_Utils._Validate(Forward,
"Forward
", V_BOOLEAN) Then GoTo Finally
517 If Start
<=
0 Or Start
> Len(InputStr) Then GoTo Finally
520 sOutput =
""
521 Set oTextSearch = SF_Utils._GetUNOService(
"TextSearch
")
522 ' Set pattern search options
523 vOptions = SF_Utils._GetUNOService(
"SearchOptions
")
525 .searchString = Regex
526 If CaseSensitive Then .transliterateFlags =
0 Else .transliterateFlags = com.sun.star.i18n.TransliterationModules.IGNORE_CASE
530 .setOptions(vOptions)
533 vResult = .searchForward(InputStr, Start -
1, lEnd)
536 vResult = .searchBackward(InputStr, Start, lEnd -
1)
539 ' https://api.libreoffice.org/docs/idl/ref/structcom_1_1sun_1_1star_1_1util_1_1SearchResult.html
541 If .subRegExpressions
>=
1 Then
543 Start = .startOffset(
0) +
1
544 lEnd = .endOffset(
0) +
1
546 Start = .endOffset(
0) +
1
547 lEnd = .startOffset(
0) +
1
549 sOutput = Mid(InputStr, Start, lEnd - Start)
557 SF_Utils._ExitFunction(cstThisSub)
561 End Function
' ScriptForge.SF_String.FindRegex
563 REM -----------------------------------------------------------------------------
564 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
565 ''' Return the actual value of the given property
566 ''' Args:
567 ''' PropertyName: the name of the property as a string
568 ''' Returns:
569 ''' The actual value of the property
570 ''' Exceptions
571 ''' ARGUMENTERROR The property does not exist
573 Const cstThisSub =
"String.GetProperty
"
574 Const cstSubArgs =
"PropertyName
"
576 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
580 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
581 If Not SF_Utils._Validate(PropertyName,
"PropertyName
", V_STRING, Properties()) Then GoTo Catch
585 Select Case UCase(PropertyName)
586 Case
"SFCR
" : GetProperty = sfCR
587 Case
"SFCRLF
" : GetProperty = sfCRLF
588 Case
"SFLF
" : GetProperty = sfLF
589 Case
"SFNEWLINE
" : GetProperty = sfNEWLINE
590 Case
"SFTAB
" : GetProperty = sfTAB
595 SF_Utils._ExitFunction(cstThisSub)
599 End Function
' ScriptForge.SF_String.GetProperty
601 REM -----------------------------------------------------------------------------
602 Public Function HashStr(Optional ByVal InputStr As Variant _
603 , Optional ByVal Algorithm As Variant _
605 ''' Return an hexadecimal string representing a checksum of the given input string
606 ''' Next algorithms are supported: MD5, SHA1, SHA224, SHA256, SHA384 and SHA512
607 ''' Args:
608 ''' InputStr: the string to be hashed
609 ''' Algorithm: The hashing algorithm to use
610 ''' Returns:
611 ''' The requested checksum as a string. Hexadecimal digits are lower-cased
612 ''' A zero-length string when an error occurred
613 ''' Example:
614 ''' Print SF_String.HashStr(
"œ∑¡™£¢∞§¶•ªº–≠œ∑´®†¥¨ˆøπ“‘åß∂ƒ©˙∆˚¬
",
"MD5
")
' 616eb9c513ad07cd02924b4d285b9987
616 Dim sHash As String
' Return value
617 Const cstPyHelper =
"$
" & "_SF_String__HashStr
"
618 Const cstThisSub =
"String.HashStr
"
619 Const cstSubArgs =
"InputStr, Algorithm=
""MD5
""|
""SHA1
""|
""SHA224
""|
""SHA256
""|
""SHA384
""|
""SHA512
"""
621 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
625 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
626 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
627 If Not SF_Utils._Validate(Algorithm,
"Algorithm
", V_STRING _
628 , Array(
"MD5
",
"SHA1
",
"SHA224
",
"SHA256
",
"SHA384
",
"SHA512
")) Then GoTo Finally
632 With ScriptForge.SF_Session
633 sHash = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper
& cstPyHelper _
634 , InputStr, LCase(Algorithm))
639 SF_Utils._ExitFunction(cstThisSub)
643 End Function
' ScriptForge.SF_String.HashStr
645 REM -----------------------------------------------------------------------------
646 Public Function HtmlEncode(Optional ByRef InputStr As Variant) As String
647 ''' &-encoding of the input string (e.g.
"é
" becomes
"&eacute;
" or numeric equivalent
648 ''' Args:
649 ''' InputStr: the input string
650 ''' Returns:
651 ''' the encoded string
652 ''' Examples:
653 ''' SF_String.HtmlEncode(
"<a href=
""https://a.b.com
"">From α to ω
</a
>")
654 ''' returns
"&lt;a href=
&quot;https://a.b.com
&quot;
&gt;From
&#
945; to
&#
969;
&lt;/a
&gt;
"
656 Dim sEncode As String
' Return value
657 Dim lPos As Long
' Position in InputStr
658 Dim sChar As String
' A single character extracted from InputStr
660 Const cstThisSub =
"String.HtmlEncode
"
661 Const cstSubArgs =
"InputStr
"
663 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
664 sEncode =
""
667 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
668 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
672 If Len(InputStr)
> 0 Then
675 Do While lPos
<= Len(sEncode)
676 sChar = Mid(sEncode, lPos,
1)
677 ' Leave as is or encode every single char
679 Case
"""" : sChar =
"&quot;
"
680 Case
"&" : sChar =
"&amp;
"
681 Case
"<" : sChar =
"&lt;
"
682 Case
">" : sChar =
"&gt;
"
683 Case
"'" : sChar =
"&apos;
"
684 Case
":
",
"/
",
"?
",
"#
",
"[
",
"]
",
"@
" ' Reserved characters
685 Case SF_String.sfCR : sChar =
"" ' Carriage return
686 Case SF_String.sfLF : sChar =
"<br
>" ' Line Feed
688 Case
"€
" : sChar =
"&euro;
"
689 Case Else : sChar =
"&#
" & Asc(sChar)
& ";
"
691 If Len(sChar) =
1 Then
692 Mid(sEncode, lPos,
1) = sChar
694 sEncode = Left(sEncode, lPos -
1)
& sChar
& Mid(sEncode, lPos +
1)
696 lPos = lPos + Len(sChar)
702 SF_Utils._ExitFunction(cstThisSub)
706 End Function
' ScriptForge.SF_String.HtmlEncode
708 REM -----------------------------------------------------------------------------
709 Public Function IsADate(Optional ByRef InputStr As Variant _
710 , Optional ByVal DateFormat _
712 ''' Return True if the string is a valid date respecting the given format
713 ''' Args:
714 ''' InputStr: the input string
715 ''' DateFormat: either YYYY-MM-DD (default), DD-MM-YYYY or MM-DD-YYYY
716 ''' The dash (-) may be replaced by a dot (.), a slash (/) or a space
717 ''' Returns:
718 ''' True if the string contains a valid date and there is at least one character
719 ''' False otherwise or if the date format is invalid
720 ''' Examples:
721 ''' SF_String.IsADate(
"2019-
12-
31",
"YYYY-MM-DD
") returns True
723 Dim bADate As Boolean
' Return value
724 Dim sFormat As String
' Alias for DateFormat
725 Dim iYear As Integer
' Alias of year in input string
726 Dim iMonth As Integer
' Alias of month in input string
727 Dim iDay As Integer
' Alias of day in input string
728 Dim dDate As Date
' Date value
729 Const cstFormat =
"YYYY-MM-DD
" ' Default date format
730 Const cstFormatRegex =
"(YYYY[- /.]MM[- /.]DD|MM[- /.]DD[- /.]YYYY|DD[- /.]MM[- /.]YYYY)
"
731 ' The regular expression the format must match
732 Const cstThisSub =
"String.IsADate
"
733 Const cstSubArgs =
"InputStr, [DateFormat=
""" & cstFormat
& """]
"
735 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
739 If IsMissing(DateFormat) Or IsEmpty(DateFormat) Then DateFormat =
"YYYY-MM-DD
"
740 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
741 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
742 If Not SF_Utils._Validate(DateFormat,
"DateFormat
", V_STRING) Then GoTo Finally
744 sFormat = UCase(DateFormat)
745 If Len(sFormat)
<> Len(cstFormat)Then GoTo Finally
746 If sFormat
<> cstFormat Then
' Do not check if default format
747 If Not SF_String.IsRegex(sFormat, cstFormatRegex) Then GoTo Finally
751 If Len(InputStr) = Len(DateFormat) Then
752 ' Extract the date components YYYY, MM, DD from the input string
753 iYear = CInt(Mid(InputStr, InStr(sFormat,
"YYYY
"),
4))
754 iMonth = CInt(Mid(InputStr, InStr(sFormat,
"MM
"),
2))
755 iDay = CInt(Mid(InputStr, InStr(sFormat,
"DD
"),
2))
756 ' Check the validity of the date
757 On Local Error GoTo NotADate
758 dDate = DateSerial(iYear, iMonth, iDay)
759 bADate = True
' Statement reached only if no error
764 SF_Utils._ExitFunction(cstThisSub)
769 On Error GoTo
0 ' Reset the error object
771 End Function
' ScriptForge.SF_String.IsADate
773 REM -----------------------------------------------------------------------------
774 Public Function IsAlpha(Optional ByRef InputStr As Variant) As Boolean
775 ''' Return True if all characters in the string are alphabetic
776 ''' Alphabetic characters are those characters defined in the Unicode character database as “Letter”
777 ''' Args:
778 ''' InputStr: the input string
779 ''' Returns:
780 ''' True if the string is alphabetic and there is at least one character, False otherwise
781 ''' Examples:
782 ''' SF_String.IsAlpha(
"àénΣlPµ
") returns True
783 ''' Note:
784 ''' Use SF_String.IsRegex(
"...
", REGEXALPHA) to limit characters to latin alphabet
786 Dim bAlpha As Boolean
' Return value
787 Dim lLength As Long
' Length of InputStr
788 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
789 Dim oLocale As Object
' com.sun.star.lang.Locale
790 Dim lType As Long
' com.sun.star.i18n.KCharacterType
791 Dim lLETTER As Long : lLETTER = com.sun.star.i18n.KCharacterType.LETTER
793 Const cstThisSub =
"String.IsAlpha
"
794 Const cstSubArgs =
"InputStr
"
796 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
800 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
801 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
805 lLength = Len(InputStr)
806 If lLength
> 0 Then
807 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
808 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
809 For i =
0 To lLength -
1
810 lType = oChar.getCharacterType(InputStr, i, oLocale)
811 bAlpha = ( (lType And lLETTER) = lLETTER )
812 If Not bAlpha Then Exit For
818 SF_Utils._ExitFunction(cstThisSub)
822 End Function
' ScriptForge.SF_String.IsAlpha
824 REM -----------------------------------------------------------------------------
825 Public Function IsAlphaNum(Optional ByRef InputStr As Variant) As Boolean
826 ''' Return True if all characters in the string are alphabetic, digits or
"_
" (underscore)
827 ''' The first character must not be a digit
828 ''' Args:
829 ''' InputStr: the input string
830 ''' Returns:
831 ''' True if the string is alphanumeric and there is at least one character, False otherwise
832 ''' Examples:
833 ''' SF_String.IsAlphaNum(
"_ABC_123456_abcàénΣlPµ
") returns True
835 Dim bAlphaNum As Boolean
' Return value
836 Dim sInputStr As String
' Alias of InputStr without underscores
837 Dim sFirst As String
' Leftmost character of InputStr
838 Dim lLength As Long
' Length of InputStr
839 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
840 Dim oLocale As Object
' com.sun.star.lang.Locale
841 Dim lType As Long
' com.sun.star.i18n.KCharacterType
842 Dim lLETTER As Long : lLETTER = com.sun.star.i18n.KCharacterType.LETTER
843 Dim lDIGIT As Long : lDIGIT = com.sun.star.i18n.KCharacterType.DIGIT
845 Const cstThisSub =
"String.IsAlphaNum
"
846 Const cstSubArgs =
"InputStr
"
848 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
852 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
853 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
857 lLength = Len(InputStr)
858 If lLength
> 0 Then
859 sFirst = Left(InputStr,
1)
860 bAlphanum = ( sFirst
< "0" Or sFirst
> "9" )
862 sInputStr = Replace(InputStr,
"_
",
"A
")
' Replace by an arbitrary alphabetic character
863 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
864 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
865 For i =
0 To lLength -
1
866 lType = oChar.getCharacterType(sInputStr, i, oLocale)
867 bAlphaNum = ( (lType And lLETTER) = lLETTER _
868 Or (lType And lDIGIT) = lDIGIT )
869 If Not bAlphaNum Then Exit For
875 IsAlphaNum = bAlphaNum
876 SF_Utils._ExitFunction(cstThisSub)
880 End Function
' ScriptForge.SF_String.IsAlphaNum
882 REM -----------------------------------------------------------------------------
883 Public Function IsAscii(Optional ByRef InputStr As Variant) As Boolean
884 ''' Return True if all characters in the string are Ascii characters
885 ''' Ascii characters are those characters defined between
&H00 and
&H7F
886 ''' Args:
887 ''' InputStr: the input string
888 ''' Returns:
889 ''' True if the string is Ascii and there is at least one character, False otherwise
890 ''' Examples:
891 ''' SF_String.IsAscii(
"a%?,
25") returns True
893 Dim bAscii As Boolean
' Return value
894 Dim lLength As Long
' Length of InputStr
895 Dim sChar As String
' Single character
897 Const cstThisSub =
"String.IsAscii
"
898 Const cstSubArgs =
"InputStr
"
900 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
904 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
905 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
909 lLength = Len(InputStr)
910 If lLength
> 0 Then
912 sChar = Mid(InputStr, i,
1)
913 bAscii = ( Asc(sChar)
<=
127 )
914 If Not bAscii Then Exit For
920 SF_Utils._ExitFunction(cstThisSub)
924 End Function
' ScriptForge.SF_String.IsAscii
926 REM -----------------------------------------------------------------------------
927 Public Function IsDigit(Optional ByRef InputStr As Variant) As Boolean
928 ''' Return True if all characters in the string are digits
929 ''' Args:
930 ''' InputStr: the input string
931 ''' Returns:
932 ''' True if the string contains only digits and there is at least one character, False otherwise
933 ''' Examples:
934 ''' SF_String.IsDigit(
"123456") returns True
936 Dim bDigit As Boolean
' Return value
937 Const cstThisSub =
"String.IsDigit
"
938 Const cstSubArgs =
"InputStr
"
940 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
944 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
945 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
949 If Len(InputStr)
> 0 Then bDigit = SF_String.IsRegex(InputStr, REGEXDIGITS, CaseSensitive := False)
953 SF_Utils._ExitFunction(cstThisSub)
957 End Function
' ScriptForge.SF_String.IsDigit
959 REM -----------------------------------------------------------------------------
960 Public Function IsEmail(Optional ByRef InputStr As Variant) As Boolean
961 ''' Return True if the string is a valid email address
962 ''' Args:
963 ''' InputStr: the input string
964 ''' Returns:
965 ''' True if the string contains an email address and there is at least one character, False otherwise
966 ''' Examples:
967 ''' SF_String.IsEmail(
"first.last@something.org
") returns True
969 Dim bEmail As Boolean
' Return value
970 Const cstThisSub =
"String.IsEmail
"
971 Const cstSubArgs =
"InputStr
"
973 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
977 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
978 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
982 If Len(InputStr)
> 0 Then bEmail = SF_String.IsRegex(InputStr, REGEXEMAIL, CaseSensitive := False)
986 SF_Utils._ExitFunction(cstThisSub)
990 End Function
' ScriptForge.SF_String.IsEmail
992 REM -----------------------------------------------------------------------------
993 Public Function IsFileName(Optional ByRef InputStr As Variant _
994 , Optional ByVal OSName As Variant _
996 ''' Return True if the string is a valid filename in a given operating system
997 ''' Args:
998 ''' InputStr: the input string
999 ''' OSName: Windows, Linux, macOS or Solaris
1000 ''' The default is the current operating system on which the script is run
1001 ''' Returns:
1002 ''' True if the string contains a valid filename and there is at least one character, False otherwise
1003 ''' Examples:
1004 ''' SF_String.IsFileName(
"/home/a file name.odt
",
"LINUX
") returns True
1006 Dim bFileName As Boolean
' Return value
1007 Dim sRegex As String
' Regex to apply depending on OS
1008 Const cstThisSub =
"String.IsFileName
"
1009 Const cstSubArgs =
"InputStr, [OSName=
""Windows
""|
""Linux
""|
""macOS
""|Solaris
""]
"
1011 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1015 If IsMissing(OSName) Or IsEmpty(OSName) Then
1016 If _SF_.OSname =
"" Then _SF_.OSName = SF_Platform.OSName
1017 OSName = _SF_.OSName
1019 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1020 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1021 If Not SF_Utils._Validate(OSName,
"OSName
", V_STRING, Array(
"Windows
",
"Linux
",
"macOS
",
"Solaris
")) Then GoTo Finally
1025 If Len(InputStr)
> 0 Then
1026 Select Case UCase(OSName)
1027 Case
"LINUX
",
"MACOS
",
"SOLARIS
" : sRegex = REGEXFILELINUX
1028 Case
"WINDOWS
" : sRegex = REGEXFILEWIN
1030 bFileName = SF_String.IsRegex(InputStr, sRegex, CaseSensitive := False)
1034 IsFileName = bFileName
1035 SF_Utils._ExitFunction(cstThisSub)
1039 End Function
' ScriptForge.SF_String.IsFileName
1041 REM -----------------------------------------------------------------------------
1042 Public Function IsHexDigit(Optional ByRef InputStr As Variant) As Boolean
1043 ''' Return True if all characters in the string are hexadecimal digits
1044 ''' Args:
1045 ''' InputStr: the input string
1046 ''' Returns:
1047 ''' True if the string contains only hexadecimal igits and there is at least one character
1048 ''' The prefixes
"0x
" and
"&H
" are admitted
1049 ''' False otherwise
1050 ''' Examples:
1051 ''' SF_String.IsHexDigit(
"&H00FF
") returns True
1053 Dim bHexDigit As Boolean
' Return value
1054 Const cstThisSub =
"String.IsHexDigit
"
1055 Const cstSubArgs =
"InputStr
"
1057 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1061 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1062 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1066 If Len(InputStr)
> 0 Then bHexDigit = SF_String.IsRegex(InputStr, REGEXHEXA, CaseSensitive := False)
1069 IsHexDigit = bHexDigit
1070 SF_Utils._ExitFunction(cstThisSub)
1074 End Function
' ScriptForge.SF_String.IsHexDigit
1076 REM -----------------------------------------------------------------------------
1077 Public Function IsIBAN(Optional ByVal InputStr As Variant) As Boolean
1078 ''' Returns True if the input string is a valid International Bank Account Number
1079 ''' Read https://en.wikipedia.org/wiki/International_Bank_Account_Number
1080 ''' Args:
1081 ''' InputStr: the input string
1082 ''' Returns:
1083 ''' True if the string contains a valid IBAN number. The comparison is not case-sensitive
1084 ''' Examples:
1085 ''' SF_String.IsIBAN(
"BR15
0000 0000 0000 1093 2840 814 P2
") returns True
1087 Dim bIBAN As Boolean
' Return value
1088 Dim sIBAN As String
' Transformed input string
1089 Dim sChar As String
' A single character
1090 Dim sLetter As String
' Integer representation of letters
1091 Dim iIndex As Integer
' Index in IBAN string
1092 Dim sLong As String
' String representation of a Long
1093 Dim iModulo97 As Integer
' Remainder of division by
97
1095 Const cstThisSub =
"String.IsIBAN
"
1096 Const cstSubArgs =
"InputStr
"
1098 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1102 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1103 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1107 sIBAN =
""
1108 ' 1. Remove spaces. Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
1109 ' NOT DONE: Country specific
1110 sIBAN = Replace(InputStr,
" ",
"")
1111 If Len(sIBAN)
< 5 Or Len(sIBAN)
> 34 Then GoTo Finally
1113 ' 2. Move the four initial characters to the end of the string. String is case-insensitive
1114 sIBAN = UCase(Mid(sIBAN,
5)
& Left(sIBAN,
4))
1116 ' 3. Replace each letter in the string with two digits, thereby expanding the string, where A =
10, B =
11, ..., Z =
35
1118 Do While iIndex
< Len(sIBAN)
1119 sChar = Mid(sIBAN, iIndex,
1)
1120 If sChar
>=
"A
" And sChar
<=
"Z
" Then
1121 sLetter = CStr(Asc(sChar) - Asc(
"A
") +
10)
1122 sIBAN = Left(sIBAN, iIndex -
1)
& sLetter
& Mid(sIBAN, iIndex +
1)
1124 ElseIf sChar
< "0" Or sChar
> "9" Then
' Remove any non-alphanumeric character
1131 ' 4. Interpret the string as a decimal integer and compute the remainder of that number on division by
97
1132 ' Computation is done in chunks of
9 digits
1134 sLong = Left(sIBAN,
2)
1135 Do While iIndex
<= Len(sIBAN)
1136 sLong = sLong
& Mid(sIBAN, iIndex,
7)
1137 iModulo97 = CLng(sLong) Mod
97
1138 iIndex = iIndex + Len(sLong) -
2
1139 sLong = Right(
"0" & CStr(iModulo97),
2)
' Force leading zero
1142 bIBAN = ( iModulo97 =
1 )
1146 SF_Utils._ExitFunction(cstThisSub)
1150 End Function
' ScriptForge.SF_String.IsIBAN
1152 REM -----------------------------------------------------------------------------
1153 Public Function IsIPv4(Optional ByRef InputStr As Variant) As Boolean
1154 ''' Return True if the string is a valid IPv4 address
1155 ''' Args:
1156 ''' InputStr: the input string
1157 ''' Returns:
1158 ''' True if the string contains a valid IPv4 address and there is at least one character, False otherwise
1159 ''' Examples:
1160 ''' SF_String.IsIPv4(
"192.168.1.50") returns True
1162 Dim bIPv4 As Boolean
' Return value
1163 Const cstThisSub =
"String.IsIPv4
"
1164 Const cstSubArgs =
"InputStr
"
1166 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1170 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1171 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1175 If Len(InputStr)
> 0 Then bIPv4 = SF_String.IsRegex(InputStr, REGEXIPV4, CaseSensitive := False)
1179 SF_Utils._ExitFunction(cstThisSub)
1183 End Function
' ScriptForge.SF_String.IsIPv4
1185 REM -----------------------------------------------------------------------------
1186 Public Function IsLike(Optional ByRef InputStr As Variant _
1187 , Optional ByVal Pattern As Variant _
1188 , Optional ByVal CaseSensitive As Variant _
1190 ''' Returns True if the whole input string matches a given pattern containing wildcards
1191 ''' Args:
1192 ''' InputStr: the input string
1193 ''' Pattern: the pattern as a string
1194 ''' Admitted wildcard are: the
"?
" represents any single character
1195 ''' the
"*
" represents zero, one, or multiple characters
1196 ''' CaseSensitive: default = False
1197 ''' Returns:
1198 ''' True if a match is found
1199 ''' Zero-length input or pattern strings always return False
1200 ''' Examples:
1201 ''' SF_String.IsLike(
"aAbB
",
"?A*
") returns True
1202 ''' SF_String.IsLike(
"C:\a\b\c\f.odb
",
"?:*.*
") returns True
1204 Dim bLike As Boolean
' Return value
1205 ' Build an equivalent regular expression by escaping the special characters present in Pattern
1206 Dim sRegex As String
' Equivalent regular expression
1207 Const cstSpecialChars =
"\,^,$,.,|,+,(,),[,{,?,*
" ' List of special chars in regular expressions
1208 Const cstEscapedChars =
"\\,\^,\$,\.,\|,\+,\(,\),\[,\{,.,.*
"
1210 Const cstThisSub =
"String.IsLike
"
1211 Const cstSubArgs =
"InputStr, Pattern, [CaseSensitive=False]
"
1213 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1217 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1218 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1219 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1220 If Not SF_Utils._Validate(Pattern,
"Pattern
", V_STRING) Then GoTo Finally
1221 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1225 If Len(InputStr)
> 0 And Len(Pattern)
> 0 Then
1226 ' Substitute special chars by escaped chars
1227 sRegex = SF_String.ReplaceStr(Pattern, Split(cstSPecialChars,
",
"), Split(cstEscapedChars,
",
"))
1228 bLike = SF_String.IsRegex(InputStr, sRegex, CaseSensitive)
1233 SF_Utils._ExitFunction(cstThisSub)
1237 End Function
' ScriptForge.SF_String.IsLike
1239 REM -----------------------------------------------------------------------------
1240 Public Function IsLower(Optional ByRef InputStr As Variant) As Boolean
1241 ''' Return True if all characters in the string are in lower case
1242 ''' Non alphabetic characters are ignored
1243 ''' Args:
1244 ''' InputStr: the input string
1245 ''' Returns:
1246 ''' True if the string contains only lower case characters and there is at least one character, False otherwise
1247 ''' Examples:
1248 ''' SF_String.IsLower(
"abc
'(-xyz
") returns True
1250 Dim bLower As Boolean
' Return value
1251 Const cstThisSub =
"String.IsLower
"
1252 Const cstSubArgs =
"InputStr
"
1254 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1258 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1259 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1263 If Len(InputStr)
> 0 Then bLower = ( StrComp(InputStr, LCase(InputStr),
1) =
0 )
1267 SF_Utils._ExitFunction(cstThisSub)
1271 End Function
' ScriptForge.SF_String.IsLower
1273 REM -----------------------------------------------------------------------------
1274 Public Function IsPrintable(Optional ByRef InputStr As Variant) As Boolean
1275 ''' Return True if all characters in the string are printable
1276 ''' In particular, control characters (Ascii
<=
1F) are not printable
1277 ''' Args:
1278 ''' InputStr: the input string
1279 ''' Returns:
1280 ''' True if the string is printable and there is at least one character, False otherwise
1281 ''' Examples:
1282 ''' SF_String.IsPrintable(
"àén ΣlPµ Русский
") returns True
1284 Dim bPrintable As Boolean
' Return value
1285 Dim lLength As Long
' Length of InputStr
1286 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
1287 Dim oLocale As Object
' com.sun.star.lang.Locale
1288 Dim lType As Long
' com.sun.star.i18n.KCharacterType
1289 Dim sChar As String
' A single character
1290 Dim lPRINTABLE As Long : lPRINTABLE = com.sun.star.i18n.KCharacterType.PRINTABLE
1292 Const cstThisSub =
"String.IsPrintable
"
1293 Const cstSubArgs =
"InputStr
"
1295 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1299 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1300 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1304 lLength = Len(InputStr)
1305 If lLength
> 0 Then
1306 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
1307 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
1308 For i =
0 To lLength -
1
1309 sChar = Mid(InputStr, i +
1,
1)
1310 lType = oChar.getCharacterType(sChar,
0, oLocale)
1311 ' Parenthses (), [], {} have a KCharacterType =
0
1312 bPrintable = ( (lType And lPRINTABLE) = lPRINTABLE Or (lType =
0 And Asc(sChar)
<=
127) )
1313 If Not bPrintable Then Exit For
1318 IsPrintable = bPrintable
1319 SF_Utils._ExitFunction(cstThisSub)
1323 End Function
' ScriptForge.SF_String.IsPrintable
1325 REM -----------------------------------------------------------------------------
1326 Public Function IsRegex(Optional ByRef InputStr As Variant _
1327 , Optional ByVal Regex As Variant _
1328 , Optional ByVal CaseSensitive As Variant _
1330 ''' Returns True if the whole input string matches a given regular expression
1331 ''' Args:
1332 ''' InputStr: the input string
1333 ''' Regex: the regular expression as a string
1334 ''' CaseSensitive: default = False
1335 ''' Returns:
1336 ''' True if a match is found
1337 ''' Zero-length input or regex strings always return False
1338 ''' Examples:
1339 ''' SF_String.IsRegex(
"aAbB
",
"[A-Za-z]+
") returns True
1341 Dim bRegex As Boolean
' Return value
1342 Dim lStart As Long
' Must be
1
1343 Dim sMatch As String
' Matching string
1344 Const cstBegin =
"^
" ' Beginning of line symbol
1345 Const cstEnd =
"$
" ' End of line symbol
1346 Const cstThisSub =
"String.IsRegex
"
1347 Const cstSubArgs =
"InputStr, Regex, [CaseSensitive=False]
"
1349 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1353 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1354 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1355 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1356 If Not SF_Utils._Validate(Regex,
"Regex
", V_STRING) Then GoTo Finally
1357 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1361 If Len(InputStr)
> 0 And Len(Regex)
> 0 Then
1362 ' Whole string must match Regex
1364 If Left(Regex,
1)
<> cstBegin Then Regex = cstBegin
& Regex
1365 If Right(Regex,
1)
<> cstEnd Then Regex = Regex
& cstEnd
1366 sMatch = SF_String.FindRegex(InputStr, Regex, lStart, CaseSensitive)
1368 bRegex = ( lStart =
1 And Len(sMatch) = Len(InputStr) )
1373 SF_Utils._ExitFunction(cstThisSub)
1377 End Function
' ScriptForge.SF_String.IsRegex
1379 REM -----------------------------------------------------------------------------
1380 Public Function IsSheetName(Optional ByRef InputStr As Variant) As Boolean
1381 ''' Return True if the input string can serve as a valid Calc sheet name
1382 ''' The sheet name must not contain the characters [ ] * ? : / \
1383 ''' or the character
' (apostrophe) as first or last character.
1385 ''' Args:
1386 ''' InputStr: the input string
1387 ''' Returns:
1388 ''' True if the string is validated as a potential Calc sheet name, False otherwise
1389 ''' Examples:
1390 ''' SF_String.IsSheetName(
"1àbc +
""def
""") returns True
1392 Dim bSheetName As Boolean
' Return value
1393 Const cstThisSub =
"String.IsSheetName
"
1394 Const cstSubArgs =
"InputStr
"
1396 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1400 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1401 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1405 If Len(InputStr)
> 0 Then
1406 If Left(InputStr,
1) =
"'" Or Right(InputStr,
1) =
"'" Then
1407 ElseIf InStr(InputStr,
"[
") _
1408 + InStr(InputStr,
"]
") _
1409 + InStr(InputStr,
"*
") _
1410 + InStr(InputStr,
"?
") _
1411 + InStr(InputStr,
":
") _
1412 + InStr(InputStr,
"/
") _
1413 + InStr(InputStr,
"\
") _
1420 IsSheetName = bSheetName
1421 SF_Utils._ExitFunction(cstThisSub)
1425 End Function
' ScriptForge.SF_String.IsSheetName
1427 REM -----------------------------------------------------------------------------
1428 Public Function IsTitle(Optional ByRef InputStr As Variant) As Boolean
1429 ''' Return True if the
1st character of every word is in upper case and the other characters are in lower case
1430 ''' Args:
1431 ''' InputStr: the input string
1432 ''' Returns:
1433 ''' True if the string is capitalized and there is at least one character, False otherwise
1434 ''' Examples:
1435 ''' SF_String.IsTitle(
"This Is A Title For Jean-Pierre
") returns True
1437 Dim bTitle As Boolean
' Return value
1438 Const cstThisSub =
"String.IsTitle
"
1439 Const cstSubArgs =
"InputStr
"
1441 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1445 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1446 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1450 If Len(InputStr)
> 0 Then bTitle = ( StrComp(InputStr, SF_String.Capitalize(InputStr),
1) =
0 )
1454 SF_Utils._ExitFunction(cstThisSub)
1458 End Function
' ScriptForge.SF_String.IsTitle
1460 REM -----------------------------------------------------------------------------
1461 Public Function IsUpper(Optional ByRef InputStr As Variant) As Boolean
1462 ''' Return True if all characters in the string are in upper case
1463 ''' Non alphabetic characters are ignored
1464 ''' Args:
1465 ''' InputStr: the input string
1466 ''' Returns:
1467 ''' True if the string contains only upper case characters and there is at least one character, False otherwise
1468 ''' Examples:
1469 ''' SF_String.IsUpper(
"ABC
'(-XYZ
") returns True
1471 Dim bUpper As Boolean
' Return value
1472 Const cstThisSub =
"String.IsUpper
"
1473 Const cstSubArgs =
"InputStr
"
1475 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1479 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1480 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1484 If Len(InputStr)
> 0 Then bUpper = ( StrComp(InputStr, UCase(InputStr),
1) =
0 )
1488 SF_Utils._ExitFunction(cstThisSub)
1492 End Function
' ScriptForge.SF_String.IsUpper
1494 REM -----------------------------------------------------------------------------
1495 Public Function IsUrl(Optional ByRef InputStr As Variant) As Boolean
1496 ''' Return True if the string is a valid absolute URL (Uniform Resource Locator)
1497 ''' The parsing is done by the ParseStrict method of the URLTransformer UNO service
1498 ''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XURLTransformer.html
1499 ''' Args:
1500 ''' InputStr: the input string
1501 ''' Returns:
1502 ''' True if the string contains a URL and there is at least one character, False otherwise
1503 ''' Examples:
1504 ''' SF_String.IsUrl(
"http://foo.bar/?q=Test%
20URL-encoded%
20stuff
") returns True
1506 Dim bUrl As Boolean
' Return value
1507 Const cstThisSub =
"String.IsUrl
"
1508 Const cstSubArgs =
"InputStr
"
1510 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1514 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1515 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1519 If Len(InputStr)
> 0 Then bUrl = ( Len(SF_FileSystem._ParseUrl(InputStr).Main)
> 0 )
1523 SF_Utils._ExitFunction(cstThisSub)
1527 End Function
' ScriptForge.SF_String.IsUrl
1529 REM -----------------------------------------------------------------------------
1530 Public Function IsWhitespace(Optional ByRef InputStr As Variant) As Boolean
1531 ''' Return True if all characters in the string are whitespaces
1532 ''' Whitespaces include Space(
32), HT(
9), LF(
10), VT(
11), FF(
12), CR(
13), Next Line(
133), No-break space(
160),
1533 ''' Line separator(
8232), Paragraph separator(
8233)
1534 ''' Args:
1535 ''' InputStr: the input string
1536 ''' Returns:
1537 ''' True if the string contains only whitespaces and there is at least one character, False otherwise
1538 ''' Examples:
1539 ''' SF_String.IsWhitespace(
" " & Chr(
9)
& Chr(
10)) returns True
1541 Dim bWhitespace As Boolean
' Return value
1542 Const cstThisSub =
"String.IsWhitespace
"
1543 Const cstSubArgs =
"InputStr
"
1545 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1549 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1550 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1554 If Len(InputStr)
> 0 Then bWhitespace = SF_String.IsRegex(InputStr, REGEXWHITESPACES, CaseSensitive := False)
1557 IsWhitespace = bWhitespace
1558 SF_Utils._ExitFunction(cstThisSub)
1562 End Function
' ScriptForge.SF_String.IsWhitespace
1564 REM -----------------------------------------------------------------------------
1565 Public Function JustifyCenter(Optional ByRef InputStr As Variant _
1566 , Optional ByVal Length As Variant _
1567 , Optional ByVal Padding As Variant _
1569 ''' Return the input string center justified
1570 ''' Args:
1571 ''' InputStr: the input string
1572 ''' Length: the resulting string length (default = length of input string)
1573 ''' Padding: the padding (single) character (default = the ascii space)
1574 ''' Returns:
1575 ''' The input string without its leading and trailing white spaces
1576 ''' completed left and right up to a total length of Length with the character Padding
1577 ''' If the input string is empty, the returned string is empty too
1578 ''' If the requested length is shorter than the center justified input string,
1579 ''' then the returned string is truncated
1580 ''' Examples:
1581 ''' SF_String.JustifyCenter(
" ABCDE
", Padding :=
"x
") returns
"xxABCDEFxx
"
1583 Dim sJustify As String
' Return value
1584 Dim lLength As Long
' Length of input string
1585 Dim lJustLength As Long
' Length of trimmed input string
1586 Dim sPadding As String
' Series of Padding characters
1587 Const cstThisSub =
"String.JustifyCenter
"
1588 Const cstSubArgs =
"InputStr, [length=Len(InputStr)], [Padding=
"" ""]
"
1590 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1591 sJustify =
""
1594 If IsMissing(Length) Or IsEmpty(Length) Then Length =
0
1595 If IsMissing(Padding) Or IsMissing(Padding) Then Padding =
" "
1596 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1597 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1598 If Not SF_Utils._Validate(Length,
"Length
", V_NUMERIC) Then GoTo Finally
1599 If Not SF_Utils._Validate(Padding,
"Padding
", V_STRING) Then GoTo Finally
1601 If Len(Padding) =
0 Then Padding =
" " Else Padding = Left(Padding,
1)
1604 lLength = Len(InputStr)
1605 If Length =
0 Then Length = lLength
1606 If lLength
> 0 Then
1607 sJustify = SF_String.TrimExt(InputStr)
' Trim left and right
1608 lJustLength = Len(sJustify)
1609 If lJustLength
> Length Then
1610 sJustify = Mid(sJustify, Int((lJustLength - Length) /
2) +
1, Length)
1611 ElseIf lJustLength
< Length Then
1612 sPadding = String(Int((Length - lJustLength) /
2), Padding)
1613 sJustify = sPadding
& sJustify
& sPadding
1614 If Len(sJustify)
< Length Then sJustify = sJustify
& Padding
' One Padding char is lacking when lJustLength is odd
1619 JustifyCenter = sJustify
1620 SF_Utils._ExitFunction(cstThisSub)
1624 End Function
' ScriptForge.SF_String.JustifyCenter
1626 REM -----------------------------------------------------------------------------
1627 Public Function JustifyLeft(Optional ByRef InputStr As Variant _
1628 , Optional ByVal Length As Variant _
1629 , Optional ByVal Padding As Variant _
1631 ''' Return the input string left justified
1632 ''' Args:
1633 ''' InputStr: the input string
1634 ''' Length: the resulting string length (default = length of input string)
1635 ''' Padding: the padding (single) character (default = the ascii space)
1636 ''' Returns:
1637 ''' The input string without its leading white spaces
1638 ''' filled up to a total length of Length with the character Padding
1639 ''' If the input string is empty, the returned string is empty too
1640 ''' If the requested length is shorter than the left justified input string,
1641 ''' then the returned string is truncated
1642 ''' Examples:
1643 ''' SF_String.JustifyLeft(
" ABCDE
", Padding :=
"x
") returns
"ABCDE xxx
"
1645 Dim sJustify As String
' Return value
1646 Dim lLength As Long
' Length of input string
1647 Const cstThisSub =
"String.JustifyLeft
"
1648 Const cstSubArgs =
"InputStr, [length=Len(InputStr)], [Padding=
"" ""]
"
1650 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1651 sJustify =
""
1654 If IsMissing(Length) Or IsEmpty(Length) Then Length =
0
1655 If IsMissing(Padding) Or IsMissing(Padding) Then Padding =
" "
1656 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1657 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1658 If Not SF_Utils._Validate(Length,
"Length
", V_NUMERIC) Then GoTo Finally
1659 If Not SF_Utils._Validate(Padding,
"Padding
", V_STRING) Then GoTo Finally
1661 If Len(Padding) =
0 Then Padding =
" " Else Padding = Left(Padding,
1)
1664 lLength = Len(InputStr)
1665 If Length =
0 Then Length = lLength
1666 If lLength
> 0 Then
1667 sJustify = SF_String.ReplaceRegex(InputStr, REGEXLTRIM,
"")
' Trim left
1668 If Len(sJustify)
>= Length Then
1669 sJustify = Left(sJustify, Length)
1671 sJustify = sJustify
& String(Length - Len(sJustify), Padding)
1676 JustifyLeft = sJustify
1677 SF_Utils._ExitFunction(cstThisSub)
1681 End Function
' ScriptForge.SF_String.JustifyLeft
1683 REM -----------------------------------------------------------------------------
1684 Public Function JustifyRight(Optional ByRef InputStr As Variant _
1685 , Optional ByVal Length As Variant _
1686 , Optional ByVal Padding As Variant _
1688 ''' Return the input string right justified
1689 ''' Args:
1690 ''' InputStr: the input string
1691 ''' Length: the resulting string length (default = length of input string)
1692 ''' Padding: the padding (single) character (default = the ascii space)
1693 ''' Returns:
1694 ''' The input string without its trailing white spaces
1695 ''' preceded up to a total length of Length with the character Padding
1696 ''' If the input string is empty, the returned string is empty too
1697 ''' If the requested length is shorter than the right justified input string,
1698 ''' then the returned string is right-truncated
1699 ''' Examples:
1700 ''' SF_String.JustifyRight(
" ABCDE
", Padding :=
"x
") returns
"x ABCDE
"
1702 Dim sJustify As String
' Return value
1703 Dim lLength As Long
' Length of input string
1704 Const cstThisSub =
"String.JustifyRight
"
1705 Const cstSubArgs =
"InputStr, [length=Len(InputStr)], [Padding=
"" ""]
"
1707 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1708 sJustify =
""
1711 If IsMissing(Length) Or IsEmpty(Length) Then Length =
0
1712 If IsMissing(Padding) Or IsMissing(Padding) Then Padding =
" "
1713 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1714 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1715 If Not SF_Utils._Validate(Length,
"Length
", V_NUMERIC) Then GoTo Finally
1716 If Not SF_Utils._Validate(Padding,
"Padding
", V_STRING) Then GoTo Finally
1718 If Len(Padding) =
0 Then Padding =
" " Else Padding = Left(Padding,
1)
1721 lLength = Len(InputStr)
1722 If Length =
0 Then Length = lLength
1723 If lLength
> 0 Then
1724 sJustify = SF_String.ReplaceRegex(InputStr, REGEXRTRIM,
"")
' Trim right
1725 If Len(sJustify)
>= Length Then
1726 sJustify = Right(sJustify, Length)
1728 sJustify = String(Length - Len(sJustify), Padding)
& sJustify
1733 JustifyRight = sJustify
1734 SF_Utils._ExitFunction(cstThisSub)
1738 End Function
' ScriptForge.SF_String.JustifyRight
1740 REM -----------------------------------------------------------------------------
1741 Public Function Methods() As Variant
1742 ''' Return the list of public methods of the String service as an array
1745 "Capitalize
" _
1746 ,
"Count
" _
1747 ,
"EndWith
" _
1748 ,
"Escape
" _
1749 ,
"ExpandTabs
" _
1750 ,
"FilterNotPrintable
" _
1751 ,
"FindRegex
" _
1752 ,
"HashStr
" _
1753 ,
"HtmlEncode
" _
1754 ,
"IsADate
" _
1755 ,
"IsAlpha
" _
1756 ,
"IsAlphaNum
" _
1757 ,
"IsAscii
" _
1758 ,
"IsDigit
" _
1759 ,
"IsEmail
" _
1760 ,
"IsFileName
" _
1761 ,
"IsHexDigit
" _
1762 ,
"IsIPv4
" _
1763 ,
"IsLike
" _
1764 ,
"IsLower
" _
1765 ,
"IsPrintable
" _
1766 ,
"IsRegex
" _
1767 ,
"IsSheetName
" _
1768 ,
"IsTitle
" _
1769 ,
"IsUpper
" _
1770 ,
"IsUrl
" _
1771 ,
"IsWhitespace
" _
1772 ,
"JustifyCenter
" _
1773 ,
"JustifyLeft
" _
1774 ,
"JustifyRight
" _
1775 ,
"Quote
" _
1776 ,
"ReplaceChar
" _
1777 ,
"ReplaceRegex
" _
1778 ,
"ReplaceStr
" _
1779 ,
"Represent
" _
1780 ,
"Reverse
" _
1781 ,
"SplitLines
" _
1782 ,
"SplitNotQuoted
" _
1783 ,
"StartsWith
" _
1784 ,
"TrimExt
" _
1785 ,
"Unescape
" _
1786 ,
"Unquote
" _
1787 ,
"Wrap
" _
1790 End Function
' ScriptForge.SF_String.Methods
1792 REM -----------------------------------------------------------------------------
1793 Public Function Properties() As Variant
1794 ''' Return the list or properties as an array
1796 Properties = Array( _
1798 ,
"sfCRLF
" _
1799 ,
"sfLF
" _
1800 ,
"sfNEWLINE
" _
1801 ,
"sfTAB
" _
1804 End Function
' ScriptForge.SF_Session.Properties
1806 REM -----------------------------------------------------------------------------
1807 Public Function Quote(Optional ByRef InputStr As Variant _
1808 , Optional ByVal QuoteChar As String _
1810 ''' Return the input string surrounded with double quotes
1811 ''' Used f.i. to prepare a string field to be stored in a csv-like file
1812 ''' Args:
1813 ''' InputStr: the input string
1814 ''' QuoteChar: either
" (default) or
'
1815 ''' Returns:
1816 ''' Existing - including leading and/or trailing - double quotes are doubled
1817 ''' Examples:
1818 ''' SF_String.Quote(
"àé
""n ΣlPµ Русский
") returns
"""àé
""""n ΣlPµ Русский
"""
1820 Dim sQuote As String
' Return value
1821 Const cstDouble =
"""" : Const cstSingle =
"'"
1822 Const cstEscape =
"\
"
1823 Const cstThisSub =
"String.Quote
"
1824 Const cstSubArgs =
"InputStr
"
1826 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1827 sQuote =
""
1830 If IsMissing(QuoteChar) Or IsEmpty(QuoteChar) Then QuoteChar = cstDouble
1831 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1832 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1833 If Not SF_Utils._Validate(QuoteChar,
"QuoteChar
", V_STRING, Array(cstDouble, cstSingle)) Then GoTo Finally
1837 If QuoteChar = cstDouble Then
1838 sQuote = cstDouble
& Replace(InputStr, cstDouble, cstDouble
& cstDouble)
& cstDouble
1840 sQuote = Replace(InputStr, cstEscape, cstEscape
& cstEscape)
1841 sQuote = cstSingle
& Replace(sQuote, cstSingle, cstEscape
& cstSingle)
& cstSingle
1846 SF_Utils._ExitFunction(cstThisSub)
1850 End Function
' ScriptForge.SF_String.Quote
1852 REM -----------------------------------------------------------------------------
1853 Public Function ReplaceChar(Optional ByRef InputStr As Variant _
1854 , Optional ByVal Before As Variant _
1855 , Optional ByVal After As Variant _
1857 ''' Replace in InputStr all occurrences of any character from Before
1858 ''' by the corresponding character in After
1859 ''' Args:
1860 ''' InputStr: the input string on which replacements should occur
1861 ''' Before: a string of characters to replace
1 by
1 in InputStr
1862 ''' After: the replacing characters
1863 ''' Returns:
1864 ''' The new string after replacement of Nth character of Before by the Nth character of After
1865 ''' Replacements are done one by one =
> potential overlaps
1866 ''' If the length of Before is larger than the length of After,
1867 ''' the residual characters of Before are replaced by the last character of After
1868 ''' The input string when Before is the zero-length string
1869 ''' Examples: easily remove accents
1870 ''' SF_String.ReplaceChar(
"Protégez votre vie privée
",
"àâãçèéêëîïôöûüýÿ
",
"aaaceeeeiioouuyy
")
1871 ''' returns
"Protegez votre vie privee
"
1872 ''' SF_String.ReplaceChar(
"Protégez votre vie privée
", SF_String.CHARSWITHACCENT, SF_String.CHARSWITHOUTACCENT)
1874 Dim sOutput As String
' Return value
1875 Dim iCaseSensitive As Integer
' Always
0 (True)
1876 Dim sBefore As String
' A single character extracted from InputStr
1877 Dim sAfter As String
' A single character extracted from After
1878 Dim lInStr As Long
' Output of InStr()
1880 Const cstThisSub =
"String.ReplaceChar
"
1881 Const cstSubArgs =
"InputStr, Before, After
"
1883 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1884 sOutput =
""
1887 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1888 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1889 If Not SF_Utils._Validate(Before,
"Before
", V_STRING) Then GoTo Finally
1890 If Not SF_Utils._Validate(After,
"After
", V_STRING) Then GoTo Finally
1894 ' Replace standard function =
> Replace(string, before, after, start, occurrences, casesensitive)
1898 ' Replace one by one up length of Before and After
1899 If Len(Before)
> 0 Then
1901 Do While i
<= Len(sOutput)
1902 sBefore = Mid(sOutput, i,
1)
1903 lInStr = InStr(
1, Before, sBefore, iCaseSensitive)
1904 If lInStr
> 0 Then
1905 If Len(After) =
0 Then
1906 sAfter =
""
1907 ElseIf lInStr
> Len(After) Then
1908 sAfter = Right(After,
1)
1910 sAfter = Mid(After, lInStr,
1)
1912 sOutput = Left(sOutput, i -
1)
& Replace(sOutput, sBefore, sAfter, i, Empty, iCaseSensitive)
1919 ReplaceChar = sOutput
1920 SF_Utils._ExitFunction(cstThisSub)
1924 End Function
' ScriptForge.SF_String.ReplaceChar
1926 REM -----------------------------------------------------------------------------
1927 Public Function ReplaceRegex(Optional ByRef InputStr As Variant _
1928 , Optional ByVal Regex As Variant _
1929 , Optional ByRef NewStr As Variant _
1930 , Optional ByVal CaseSensitive As Variant _
1932 ''' Replace in InputStr all occurrences of a given regular expression by NewStr
1933 ''' Args:
1934 ''' InputStr: the input string where replacements should occur
1935 ''' Regex: the regular expression
1936 ''' NewStr: the replacing string
1937 ''' CaseSensitive: default = False
1938 ''' Returns:
1939 ''' The new string after all replacements
1940 ''' Examples:
1941 ''' SF_String.ReplaceRegex(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"[a-z]
",
"x
", CaseSensitive := True)
1942 ''' returns
"Lxxxx xxxxx xxxxx xxx xxxx, xxxxxxxxxxx xxxxxxxxxx xxxx.
"
1943 ''' SF_String.ReplaceRegex(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"\b[a-z]+\b
",
"x
", CaseSensitive := False)
1944 ''' returns
"x x x x x, x x x.
" (each word is replaced by x)
1947 Dim sOutput As String
' Return value
1948 Dim lStartOld As Long
' Previous start of search
1949 Dim lStartNew As Long
' Next start of search
1950 Dim sSubstring As String
' Substring to replace
1951 Const cstThisSub =
"String.ReplaceRegex
"
1952 Const cstSubArgs =
"InputStr, Regex, NewStr, [CaseSensitive=False]
"
1954 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1955 sOutput =
""
1958 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1959 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1960 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1961 If Not SF_Utils._Validate(Regex,
"Regex
", V_STRING) Then GoTo Finally
1962 If Not SF_Utils._Validate(NewStr,
"NewStr
", V_STRING) Then GoTo Finally
1963 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1967 sOutput =
""
1971 Do While lStartNew
>=
1 And lStartNew
<= Len(InputStr)
1972 sSubstring = SF_String.FindRegex(InputStr, Regex, lStartNew, CaseSensitive)
1973 If lStartNew =
0 Then
' Regex not found
1974 ' Copy remaining substring of InputStr before leaving
1975 sOutput = sOutput
& Mid(InputStr, lStartOld)
1978 ' Append the interval between
2 occurrences and the replacing string
1979 If lStartNew
> lStartOld Then sOutput = sOutput
& Mid(InputStr, lStartOld, lStartNew - lStartOld)
1980 sOutput = sOutput
& NewStr
1981 lStartOld = lStartNew + Len(sSubstring)
1982 lStartNew = lStartOld
1986 ReplaceRegex = sOutput
1987 SF_Utils._ExitFunction(cstThisSub)
1991 End Function
' ScriptForge.SF_String.ReplaceRegex
1993 REM -----------------------------------------------------------------------------
1994 Public Function ReplaceStr(Optional ByRef InputStr As Variant _
1995 , Optional ByVal OldStr As Variant _
1996 , Optional ByVal NewStr As Variant _
1997 , Optional ByVal Occurrences As Variant _
1998 , Optional ByVal CaseSensitive As Variant _
2000 ''' Replace in InputStr some or all occurrences of OldStr by NewStr
2001 ''' Args:
2002 ''' InputStr: the input string on which replacements should occur
2003 ''' OldStr: the string to replace or a
1D array of strings to replace
2004 ''' Zero-length strings are ignored
2005 ''' NewStr: the replacing string or a
1D array of replacing strings
2006 ''' If OldStr is an array
2007 ''' each occurrence of any of the items of OldStr is replaced by NewStr
2008 ''' If OldStr and NewStr are arrays
2009 ''' replacements occur one by one up to the UBound of NewStr
2010 ''' remaining OldStr(ings) are replaced by the last element of NewStr
2011 ''' Occurrences: the maximum number of replacements (
0, default, = all occurrences)
2012 ''' Is applied for each single replacement when OldStr is an array
2013 ''' CaseSensitive: True or False (default)
2014 ''' Returns:
2015 ''' The new string after replacements
2016 ''' Replacements are done one by one when OldStr is an array =
> potential overlaps
2017 ''' Examples:
2018 ''' SF_String.ReplaceStr(
"abCcdefghHij
", Array(
"c
",
"h
"), Array(
"Y
",
"Z
"), CaseSensitive := False) returns
"abYYdefgZZij
"
2020 Dim sOutput As String
' Return value
2021 Dim iCaseSensitive As Integer
' Integer alias for boolean CaseSensitive
2022 Dim vOccurrences As Variant
' Variant alias for Integer Occurrences
2023 Dim sNewStr As String
' Alias for a NewStr item
2024 Dim i As Long, j As Long
2025 Const cstThisSub =
"String.ReplaceStr
"
2026 Const cstSubArgs =
"InputStr, OldStr, NewStr, [Occurrences=
0], [CaseSensitive=False]
"
2028 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2029 sOutput =
""
2032 If IsMissing(Occurrences) Or IsEmpty(Occurrences) Then Occurrences =
0
2033 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
2034 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2035 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2036 If IsArray(OldStr) Then
2037 If Not SF_Utils._ValidateArray(OldStr,
"OldStr
",
1, V_STRING, True) Then GoTo Finally
2039 If Not SF_Utils._Validate(OldStr,
"OldStr
", V_STRING) Then GoTo Finally
2041 If IsArray(NewStr) Then
2042 If Not SF_Utils._ValidateArray(NewStr,
"NewStr
",
1, V_STRING, True) Then GoTo Finally
2044 If Not SF_Utils._Validate(NewStr,
"NewStr
", V_STRING) Then GoTo Finally
2046 If Not SF_Utils._Validate(Occurrences,
"Occurrences
", V_NUMERIC) Then GoTo Finally
2047 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
2051 ' Replace standard function =
> Replace(string, before, after, start, occurrences, casesensitive)
2053 iCaseSensitive = Iif(CaseSensitive,
0,
1)
' 1 = False ;)
2054 vOccurrences = Iif(Occurrences =
0, Empty, Occurrences)
' Empty = no limit
2055 If Not IsArray(OldStr) Then OldStr = Array(OldStr)
2056 If Not IsArray(NewStr) Then NewStr = Array(NewStr)
2058 ' Replace one by one up to UBounds of Old and NewStr
2059 j = LBound(NewStr) -
1
2060 For i = LBound(OldStr) To UBound(OldStr)
2062 If j
<= UBound(NewStr) Then sNewStr = NewStr(j)
' Else do not change
2063 If StrComp(OldStr(i), sNewStr,
1)
<> 0 Then
2064 sOutput = Replace(sOutput, OldStr(i), sNewStr,
1, vOccurrences, iCaseSensitive)
2069 ReplaceStr = sOutput
2070 SF_Utils._ExitFunction(cstThisSub)
2074 End Function
' ScriptForge.SF_String.ReplaceStr
2076 REM -----------------------------------------------------------------------------
2077 Public Function Represent(Optional ByRef AnyValue As Variant _
2078 , Optional ByVal MaxLength As Variant _
2080 ''' Return a readable (string) form of the argument, truncated at MaxLength
2081 ''' Args:
2082 ''' AnyValue: really any value (object, date, whatever)
2083 ''' MaxLength: the maximum length of the resulting string (Default =
0, unlimited)
2084 ''' Returns:
2085 ''' The argument converted or transformed into a string of a maximum length = MaxLength
2086 ''' Objects are surrounded with square brackets ([])
2087 ''' In strings, tabs and line breaks are replaced by \t, \n or \r
2088 ''' If the effective length exceeds MaxLength, the final part of the string is replaced by
" ... (N)
"
2089 ''' where N = the total length of the string before truncation
2090 ''' Examples:
2091 ''' SF_String.Represent(
"this is a usual string
") returns
"this is a usual string
"
2092 ''' SF_String.Represent(
"this is a usual string
",
15) returns
"this i ... (
22)
"
2093 ''' SF_String.Represent(
"this is a
" & Chr(
10)
& " 2-lines string
") returns
"this is a\n
2-lines string
"
2094 ''' SF_String.Represent(Empty) returns
"[EMPTY]
"
2095 ''' SF_String.Represent(Null) returns
"[NULL]
"
2096 ''' SF_String.Represent(Pi) returns
"3.142"
2097 ''' SF_String.Represent(CreateUnoService(
"com.sun.star.util.PathSettings
")) returns
"[com.sun.star.comp.framework.PathSettings]
"
2098 ''' SF_String.Represent(Array(
1,
2,
"Text
" & Chr(
9)
& "here
")) returns
"[ARRAY] (
0:
2) (
1,
2, Text\there)
"
2099 ''' Dim myDict As Variant : myDict = CreateScriptService(
"Dictionary
")
2100 ''' myDict.Add(
"A
",
1) : myDict.Add(
"B
",
2)
2101 ''' SF_String.Represent(myDict) returns
"[Dictionary] (
"A
":
1,
"B
":
2)
"
2103 Dim sRepr As String
' Return value
2104 Const cstThisSub =
"String.Represent
"
2105 Const cstSubArgs =
"AnyValue, [MaxLength=
0]
"
2107 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2108 sRepr =
""
2111 If IsMissing(AnyValue) Then AnyValue = Empty
2112 If IsMissing(MaxLength) Or IsEmpty(MaxLength) Then MaxLength =
0
2113 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2114 If Not SF_Utils._Validate(MaxLength,
"MaxLength
", V_NUMERIC) Then GoTo Finally
2118 sRepr = SF_Utils._Repr(AnyValue, MaxLength)
2119 If MaxLength
> 0 And MaxLength
< Len(sRepr) Then sRepr = sRepr
& " ... (
" & Len(sRepr)
& ")
"
2123 SF_Utils._ExitFunction(cstThisSub)
2127 End Function
' ScriptForge.SF_String.Represent
2129 REM -----------------------------------------------------------------------------
2130 Public Function Reverse(Optional ByRef InputStr As Variant) As String
2131 ''' Return the input string in reversed order
2132 ''' It is equivalent to the standard StrReverse Basic function
2133 ''' The latter requires the OpTion VBASupport
1 statement to be present in the module
2134 ''' Args:
2135 ''' InputStr: the input string
2136 ''' Returns:
2137 ''' The input string in reversed order
2138 ''' Examples:
2139 ''' SF_String.Reverse(
"abcdefghij
") returns
"jihgfedcba
"
2141 Dim sReversed As String
' Return value
2142 Dim lLength As Long
' Length of input string
2144 Const cstThisSub =
"String.Reverse
"
2145 Const cstSubArgs =
"InputSt
"
2147 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2148 sReversed =
""
2151 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2152 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2156 lLength = Len(InputStr)
2157 If lLength
> 0 Then
2158 sReversed = Space(lLength)
2159 For i =
1 To lLength
2160 Mid(sReversed, i,
1) = Mid(InputStr, lLength - i +
1)
2166 SF_Utils._ExitFunction(cstThisSub)
2170 End Function
' ScriptForge.SF_String.Reverse
2172 REM -----------------------------------------------------------------------------
2173 Public Function SetProperty(Optional ByVal PropertyName As Variant _
2174 , Optional ByRef Value As Variant _
2176 ''' Set a new value to the given property
2177 ''' Args:
2178 ''' PropertyName: the name of the property as a string
2179 ''' Value: its new value
2180 ''' Exceptions
2181 ''' ARGUMENTERROR The property does not exist
2183 Const cstThisSub =
"String.SetProperty
"
2184 Const cstSubArgs =
"PropertyName, Value
"
2186 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2190 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2191 If Not SF_Utils._Validate(PropertyName,
"PropertyName
", V_STRING, Properties()) Then GoTo Catch
2195 Select Case UCase(PropertyName)
2200 SF_Utils._ExitFunction(cstThisSub)
2204 End Function
' ScriptForge.SF_String.SetProperty
2206 REM -----------------------------------------------------------------------------
2207 Public Function SplitLines(Optional ByRef InputStr As Variant _
2208 , Optional ByVal KeepBreaks As Variant _
2210 ''' Return an array of the lines in a string, breaking at line boundaries
2211 ''' Line boundaries include LF(
10), VT(
12), CR(
13), LF+CR, File separator(
28), Group separator(
29), Record separator(
30),
2212 ''' Next Line(
133), Line separator(
8232), Paragraph separator(
8233)
2213 ''' Args:
2214 ''' InputStr: the input string
2215 ''' KeepBreaks: when True, line breaks are preserved in the output array (default = False)
2216 ''' Returns:
2217 ''' An array of all the individual lines
2218 ''' Examples:
2219 ''' SF_String.SplitLines(
"Line1
" & Chr(
10)
& "Line2
" & Chr(
13)
& "Line3
") returns (
"Line1
",
"Line2
",
"Line3
")
2220 ''' SF_String.SplitLines(
"Line1
" & Chr(
10)
& "Line2
" & Chr(
13)
& "Line3
" & Chr(
10)) returns (
"Line1
",
"Line2
",
"Line3
",
"")
2222 Dim vSplit As Variant
' Return value
2223 Dim vLineBreaks As Variant
' Array of recognized line breaks
2224 Dim vTokenizedBreaks As Variant
' Array of line breaks extended with tokens
2225 Dim sAlias As String
' Alias for input string
2226 ' The procedure uses (dirty) placeholders to identify line breaks
2227 ' The used tokens are presumed unlikely present in text strings
2228 Dim sTokenCRLF As String
' Token to identify combined CR + LF
2229 Dim sToken As String
' Token to identify any line break
2231 Const cstThisSub =
"String.SplitLines
"
2232 Const cstSubArgs =
"InputStr, [KeepBreaks=False]
"
2234 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2238 If IsMissing(KeepBreaks) Or IsEmpty(KeepBreaks) Then KeepBreaks = False
2239 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2240 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2241 If Not SF_Utils._Validate(KeepBreaks,
"KeepBreaks
", V_BOOLEAN) Then GoTo Finally
2245 ' In next list CR + LF must precede CR and LF
2246 vLineBreaks = Array(SF_String.sfCRLF, SF_String.sfLF, Chr(
12), SF_String.sfCR _
2247 , Chr(
28), Chr(
29), Chr(
30), Chr(
133), Chr(
8232), Chr(
8233))
2249 If KeepBreaks = False Then
2250 ' Replace line breaks by linefeeds and split on linefeeds
2251 vSplit = Split(SF_String.ReplaceStr(InputStr, vLineBreaks, SF_String.sfLF, CaseSensitive := False), SF_String.sfLF)
2253 sTokenCRLF = Chr(
1)
& "$
" & Chr(
2)
& "*
" & Chr(
3)
& "$
" & Chr(
1)
2254 sToken = Chr(
1)
& "$
" & Chr(
2)
& "*
" & Chr(
3)
& "$
" & Chr(
2)
2255 vTokenizedBreaks = Array() : ReDim vTokenizedBreaks(
0 To UBound(vLineBreaks))
2256 ' Extend breaks with token
2257 For i =
0 To UBound(vLineBreaks)
2258 vTokenizedBreaks(i) = Iif(i =
0, sTokenCRLF, vLineBreaks(i))
& sToken
2260 sAlias = SF_String.ReplaceStr(InputStr, vLineBreaks, vTokenizedBreaks, CaseSensitive := False)
2261 ' Suppress CRLF tokens and split
2262 vSplit = Split(Replace(sAlias, sTokenCRLF, SF_String.sfCRLF), sToken)
2267 SF_Utils._ExitFunction(cstThisSub)
2271 End Function
' ScriptForge.SF_String.SplitLines
2273 REM -----------------------------------------------------------------------------
2274 Public Function SplitNotQuoted(Optional ByRef InputStr As Variant _
2275 , Optional ByVal Delimiter As Variant _
2276 , Optional ByVal Occurrences As Variant _
2277 , Optional ByVal QuoteChar As Variant _
2279 ''' Split a string on Delimiter into an array. If Delimiter is part of a quoted (sub)string, it is ignored
2280 ''' (used f.i. for parsing of csv-like records)
2281 ''' Args:
2282 ''' InputStr: the input string
2283 ''' Might contain quoted substrings:
2284 ''' The quoting character must be the double quote (
")
2285 ''' To preserve a quoting character inside the quoted substring, use (\) or (
") as escape character
2286 ''' =
> [str\
"i
""ng] means [str
"i
"ng]
2287 ''' Delimiter: A string of one or more characters that is used to delimit the input string
2288 ''' The default is the space character
2289 ''' Occurrences: The number of substrings to return (Default =
0, meaning no limit)
2290 ''' QuoteChar: The quoting character, either
" (default) or
'
2291 ''' Returns:
2292 ''' An array whose items are chunks of the input string, Delimiter not included
2293 ''' Examples:
2294 ''' SF_String.SplitNotQuoted(
"abc def ghi
") returns (
"abc
",
"def
",
"ghi
")
2295 ''' SF_String.SplitNotQuoted(
"abc,
""def,ghi
""",
",
") returns (
"abc
",
"""def,ghi
""")
2296 ''' SF_String.SplitNotQuoted(
"abc,
""def\
"",ghi
""",
",
") returns (
"abc
",
"""def\
"",ghi
""")
2297 ''' SF_String.SplitNotQuoted(
"abc,
""def\
"",ghi
"""",
",
",
") returns (
"abc
",
"""def\
"",ghi
""",
"")
2299 Dim vSplit As Variant
' Return value
2300 Dim lDelimLen As Long
' Length of Delimiter
2301 Dim vStart As Variant
' Array of start positions of quoted strings
2302 Dim vEnd As Variant
' Array of end positions of quoted strings
2303 Dim lInStr As Long
' InStr() on input string
2304 Dim lInStrPrev As Long
' Previous value of lInputStr
2305 Dim lBound As Long
' UBound of vStart and vEnd
2306 Dim lMin As Long
' Lower bound to consider when searching vStart and vEnd
2307 Dim oCharacterClass As Object
' com.sun.star.i18n.CharacterClassification
2308 Dim oLocale As Object
' com.sun.star.lang.Locale
2309 Dim oParse As Object
' com.sun.star.i18n.ParseResult
2310 Dim sChunk As String
' Substring of InputStr
2311 Dim bSplit As Boolean
' New chunk found or not
2313 Const cstDouble =
"""" : Const cstSingle =
"'"
2314 Const cstThisSub =
"String.SplitNotQuoted
"
2315 Const cstSubArgs =
"InputStr, [Delimiter=
"" ""], [Occurrences=
0], [QuoteChar=
""" & cstDouble
& """]
"
2317 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2321 If IsMissing(Delimiter) Or IsEmpty(Delimiter) Then Delimiter =
" "
2322 If IsMissing(Occurrences) Or IsEmpty(Occurrences) Then Occurrences =
0
2323 If IsMissing(QuoteChar) Or IsEmpty(QuoteChar) Then QuoteChar = cstDouble
2324 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2325 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2326 If Not SF_Utils._Validate(Delimiter,
"Delimiter
", V_STRING) Then GoTo Finally
2327 If Not SF_Utils._Validate(Occurrences,
"Occurrences
", V_NUMERIC) Then GoTo Finally
2328 If Not SF_Utils._Validate(QuoteChar,
"QuoteChar
", V_STRING, Array(cstDouble, cstSingle)) Then GoTo Finally
2330 If Len(Delimiter) =
0 Then Delimiter =
" "
2333 If Occurrences =
1 Or InStr(
1, InputStr, Delimiter,
0) =
0 Then
' No reason to split
2334 vSplit = Array(InputStr)
2335 ElseIf InStr(
1, InputStr, QuoteChar,
0) =
0 Then
' No reason to make a complex split
2336 If Occurrences
> 0 Then vSplit = Split(InputStr, Delimiter, Occurrences) Else vSplit = Split(InputStr, Delimiter)
2338 If Occurrences
< 0 Then Occurrences =
0
2339 Set oCharacterClass = SF_Utils._GetUNOService(
"CharacterClass
")
2340 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
2342 ' Build an array of start/end positions of quoted strings containing at least
1x the Delimiter
2343 vStart = Array() : vEnd = Array()
2344 lInStr = InStr(
1, InputStr, QuoteChar)
2345 Do While lInStr
> 0
2346 lBound = UBound(vStart)
2347 ' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1i18n_1_1XCharacterClassification.html#ad5f1be91fbe86853200391f828d4166b
2348 Set oParse = oCharacterClass.parsePredefinedToken( _
2349 Iif(QuoteChar = cstDouble, com.sun.star.i18n.KParseType.DOUBLE_QUOTE_STRING, com.sun.star.i18n.KParseType.SINGLE_QUOTE_NAME) _
2350 , InputStr, lInStr -
1, oLocale,
0,
"",
0,
"")
2351 If oParse.CharLen
> 0 Then
' Is parsing successful ?
2352 ' Is there some delimiter ?
2353 If InStr(
1, oParse.DequotedNameOrString, Delimiter,
0)
> 0 Then
2354 vStart = SF_Array.Append(vStart, lInStr +
0)
2355 vEnd = SF_Array.Append(vEnd, lInStr + oParse.CharLen -
1)
2357 lInStr = InStr(lInStr + oParse.CharLen, InputStr, QuoteChar)
2363 lBound = UBound(vStart)
2364 lDelimLen = Len(Delimiter)
2365 If lBound
< 0 Then
' Usual split is applicable
2366 vSplit = Split(InputStr, Delimiter, Occurrences)
2368 ' Split chunk by chunk
2371 lInStr = InStr(
1, InputStr, Delimiter,
0)
2372 Do While lInStr
> 0
2373 If Occurrences
> 0 And Occurrences = UBound(vSplit) -
1 Then Exit Do
2375 ' Ignore found Delimiter if in quoted string
2376 For i = lMin To lBound
2377 If lInStr
< vStart(i) Then
2380 ElseIf lInStr
> vStart(i) And lInStr
< vEnd (i) Then
2384 If i = lBound Then bSplit = True Else bSplit = ( lInStr
< vStart(lMin) )
2387 ' Build next chunk and store in split array
2389 If lInStrPrev =
0 Then
' First chunk
2390 sChunk = Left(InputStr, lInStr -
1)
2392 sChunk = Mid(InputStr, lInStrPrev + lDelimLen, lInStr - lInStrPrev - lDelimLen)
2394 vSplit = SF_Array.Append(vSplit, sChunk
& "")
2397 lInStr = InStr(lInStr + lDelimLen, InputStr, Delimiter,
0)
2399 If Occurrences =
0 Or Occurrences
> UBound(vSplit) +
1 Then
2400 sChunk = Mid(InputStr, lInStrPrev + lDelimLen)
' Append last chunk
2401 vSplit = SF_Array.Append(vSplit, sChunk
& "")
2407 SplitNotQuoted = vSplit
2408 SF_Utils._ExitFunction(cstThisSub)
2412 End Function
' ScriptForge.SF_String.SplitNotQuoted
2414 REM -----------------------------------------------------------------------------
2415 Public Function StartsWith(Optional ByRef InputStr As Variant _
2416 , Optional ByVal Substring As Variant _
2417 , Optional ByVal CaseSensitive As Variant _
2419 ''' Returns True if the first characters of InputStr are identical to Substring
2420 ''' Args:
2421 ''' InputStr: the input string
2422 ''' Substring: the prefixing characters
2423 ''' CaseSensitive: default = False
2424 ''' Returns:
2425 ''' True if the comparison is satisfactory
2426 ''' False if either InputStr or Substring have a length =
0
2427 ''' False if Substr is longer than InputStr
2428 ''' Examples:
2429 ''' SF_String.StartsWith(
"abcdefg
",
"ABC
") returns True
2430 ''' SF_String.StartsWith(
"abcdefg
",
"ABC
", CaseSensitive := True) returns False
2432 Dim bStartsWith As Boolean
' Return value
2433 Dim lSub As Long
' Length of SUbstring
2434 Const cstThisSub =
"String.StartsWith
"
2435 Const cstSubArgs =
"InputStr, Substring, [CaseSensitive=False]
"
2437 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2441 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
2442 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2443 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2444 If Not SF_Utils._Validate(Substring,
"Substring
", V_STRING) Then GoTo Finally
2445 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
2449 lSub = Len(Substring)
2450 If Len(InputStr)
> 0 And lSub
> 0 And lSub
<= Len(InputStr) Then
2451 bStartsWith = ( StrComp(Left(InputStr, lSub), Substring, Iif(CaseSensitive,
1,
0)) =
0 )
2455 StartsWith = bStartsWith
2456 SF_Utils._ExitFunction(cstThisSub)
2460 End Function
' ScriptForge.SF_String.StartsWith
2462 REM -----------------------------------------------------------------------------
2463 Public Function TrimExt(Optional ByRef InputStr As Variant) As String
2464 ''' Return the input string without its leading and trailing whitespaces
2465 ''' Args:
2466 ''' InputStr: the input string
2467 ''' Returns:
2468 ''' The input string without its leading and trailing white spaces
2469 ''' Examples:
2470 ''' SF_String.TrimExt(
" ABCDE
" & Chr(
9)
& Chr(
10)
& Chr(
13)
& " ") returns
"ABCDE
"
2472 Dim sTrim As String
' Return value
2473 Const cstThisSub =
"String.TrimExt
"
2474 Const cstSubArgs =
"InputStr
"
2476 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2477 sTrim =
""
2480 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2481 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2485 If Len(InputStr)
> 0 Then
2486 sTrim = SF_String.ReplaceRegex(InputStr, REGEXLTRIM,
"")
' Trim left
2487 sTrim = SF_String.ReplaceRegex(sTrim, REGEXRTRIM,
"")
' Trim right
2492 SF_Utils._ExitFunction(cstThisSub)
2496 End Function
' ScriptForge.SF_String.TrimExt
2498 REM -----------------------------------------------------------------------------
2499 Public Function Unescape(Optional ByRef InputStr As Variant) As String
2500 ''' Convert any escaped characters in the input string
2501 ''' Args:
2502 ''' InputStr: the input string
2503 ''' Returns:
2504 ''' The input string after replacement of \\, \n, \r, \t sequences
2505 ''' Examples:
2506 ''' SF_String.Unescape(
"abc\n\tdef\\n
") returns
"abc
" & Chr(
10)
& Chr(
9)
& "def\n
"
2508 Dim sUnescape As String
' Return value
2509 Dim sToken As String
' Placeholder unlikely to be present in input string
2510 Const cstThisSub =
"String.Unescape
"
2511 Const cstSubArgs =
"InputStr
"
2513 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2514 sUnescape =
""
2517 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2518 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2522 sToken = Chr(
1)
& "$
" & Chr(
2)
& "*
" & Chr(
3)
& "$
" & Chr(
1)
' Placeholder for
"\\
"
2523 sUnescape = SF_String.ReplaceStr( InputStr _
2524 , Array(
"\\
",
"\n
",
"\r
",
"\t
", sToken) _
2525 , Array(sToken, SF_String.sfLF, SF_String.sfCR, SF_String.sfTAB,
"\
") _
2529 Unescape = sUnescape
2530 SF_Utils._ExitFunction(cstThisSub)
2534 End Function
' ScriptForge.SF_String.Unescape
2536 REM -----------------------------------------------------------------------------
2537 Public Function Unquote(Optional ByRef InputStr As Variant _
2538 , Optional ByVal QuoteChar As String _
2540 ''' Reset a quoted string to its original content
2541 ''' (used f.i. for parsing of csv-like records)
2542 ''' When the input string contains the quote character, the latter must be escaped:
2543 ''' - QuoteChar = double quote, by doubling it (
"")
2544 ''' - QuoteChar = single quote, with a preceding backslash (\
')
2545 ''' Args:
2546 ''' InputStr: the input string
2547 ''' QuoteChar: either
" (default) or
'
2548 ''' Returns:
2549 ''' The input string after removal of leading/trailing quotes and escaped single/double quotes
2550 ''' The input string if not a quoted string
2551 ''' Examples:
2552 ''' SF_String.Unquote(
"""àé
""""n ΣlPµ Русский
""") returns
"àé
""n ΣlPµ Русский
"
2554 Dim sUnquote As String
' Return value
2555 Dim oCharacterClass As Object
' com.sun.star.i18n.CharacterClassification
2556 Dim oLocale As Object
' com.sun.star.lang.Locale
2557 Dim oParse As Object
' com.sun.star.i18n.ParseResult
2558 Const cstDouble =
"""" : Const cstSingle =
"'"
2559 Const cstThisSub =
"String.Unquote
"
2560 Const cstSubArgs =
"InputStr
"
2562 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2563 sUnquote =
""
2566 If IsMissing(QuoteChar) Or IsEmpty(QuoteChar) Then QuoteChar = cstDouble
2567 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2568 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2569 If Not SF_Utils._Validate(QuoteChar,
"QuoteChar
", V_STRING, Array(cstDouble, cstSingle)) Then GoTo Finally
2573 If Left(InputStr,
1)
<> QuoteChar Then
' No need to parse further
2576 Set oCharacterClass = SF_Utils._GetUNOService(
"CharacterClass
")
2577 Set oLocale = SF_Utils._GetUNOService(
"SystemLocale
")
2579 ' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1i18n_1_1XCharacterClassification.html#ad5f1be91fbe86853200391f828d4166b
2580 Set oParse = oCharacterClass.parsePredefinedToken( _
2581 Iif(QuoteChar = cstDouble, com.sun.star.i18n.KParseType.DOUBLE_QUOTE_STRING, com.sun.star.i18n.KParseType.SINGLE_QUOTE_NAME) _
2582 , InputStr,
0, oLocale,
0,
"",
0,
"")
2583 If oParse.CharLen
> 0 Then
' Is parsing successful ?
2584 sUnquote = oParse.DequotedNameOrString
2592 SF_Utils._ExitFunction(cstThisSub)
2596 End Function
' ScriptForge.SF_String.Unquote
2598 REM -----------------------------------------------------------------------------
2599 Public Function Wrap(Optional ByRef InputStr As Variant _
2600 , Optional ByVal Width As Variant _
2601 , Optional ByVal TabSize As Variant _
2603 ''' Wraps every single paragraph in text (a string) so every line is at most Width characters long
2604 ''' Args:
2605 ''' InputStr: the input string
2606 ''' Width: the maximum number of characters in each line, default =
70
2607 ''' TabSize: before wrapping the text, the existing TAB (Chr(
9)) characters are replaced with spaces.
2608 ''' TabSize defines the TAB positions at TabSize +
1,
2 * TabSize +
1 , ... N * TabSize +
1
2609 ''' Default =
8
2610 ''' Returns:
2611 ''' Returns a zero-based array of output lines, without final newlines except the pre-existing line-breaks
2612 ''' Tabs are expanded. Symbolic line breaks are replaced by their hard equivalents
2613 ''' If the wrapped output has no content, the returned array is empty.
2614 ''' Examples:
2615 ''' SF_String.Wrap(
"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...
",
20)
2617 Dim vWrap As Variant
' Return value
2618 Dim vWrapLines
' Input string split on line breaks
2619 Dim sWrap As String
' Intermediate string
2620 Dim sLine As String
' Line after splitting on line breaks
2621 Dim lPos As Long
' Position in sLine already wrapped
2622 Dim lStart As Long
' Start position before and after regex search
2623 Dim sSpace As String
' Next whitespace
2624 Dim sChunk As String
' Next wrappable text chunk
2625 Const cstThisSub =
"String.Wrap
"
2626 Const cstSubArgs =
"InputStr, [Width=
70], [TabSize=
8]
"
2628 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2632 If IsMissing(Width) Or IsEmpty(Width) Then Width =
70
2633 If IsMissing(TabSize) Or IsEmpty(TabSize) Then TabSize =
8
2634 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2635 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2636 If Not SF_Utils._Validate(Width,
"Width
", V_NUMERIC) Then GoTo Finally
2637 If Not SF_Utils._Validate(TabSize,
"TabSize
", V_NUMERIC) Then GoTo Finally
2641 If Len(InputStr)
> 0 Then
2642 sWrap = SF_String.Unescape(InputStr)
' Replace symbolic breaks
2643 sWrap = SF_String.ExpandTabs(sWrap, TabSize)
' Interpret TABs to have a meaningful Width
2644 ' First, split full string
2645 vWrapLines = SF_String.SplitLines(sWrap, KeepBreaks := True)
' Keep pre-existing breaks
2646 If UBound(vWrapLines) =
0 And Len(sWrap)
<= Width Then
' Output a single line
2647 vWrap = Array(sWrap)
2649 ' Second, split each line on Width
2650 For Each sLine In vWrapLines
2651 If Len(sLine)
<= Width Then
2652 If UBound(vWrap)
< 0 Then vWrap = Array(sLine) Else vWrap = SF_Array.Append(vWrap, sLine)
2654 ' Scan sLine and accumulate found substrings up to Width
2657 sWrap =
""
2658 Do While lStart
<= Len(sLine)
2659 sSpace = SF_String.FindRegex(sLine, REGEXSPACES, lStart)
2660 If lStart =
0 Then lStart = Len(sLine) +
1
2661 sChunk = Mid(sLine, lPos +
1, lStart -
1 - lPos + Len(sSpace))
2662 If Len(sWrap) + Len(sChunk)
< Width Then
' Add chunk to current piece of line
2663 sWrap = sWrap
& sChunk
2664 Else
' Save current line and initialize next one
2665 If UBound(vWrap)
< 0 Then vWrap = Array(sWrap) Else vWrap = SF_Array.Append(vWrap, sWrap)
2668 lPos = lPos + Len(sChunk)
2671 ' Add last chunk
2672 If Len(sWrap)
> 0 Then
2673 If UBound(vWrap)
< 0 Then vWrap = Array(sWrap) Else vWrap = SF_Array.Append(vWrap, sWrap)
2682 SF_Utils._ExitFunction(cstThisSub)
2686 End Function
' ScriptForge.SF_String.Wrap
2688 REM ============================================================= PRIVATE METHODS
2690 REM -----------------------------------------------------------------------------
2691 Private Function _Repr(ByRef pvString As String) As String
2692 ''' Convert an arbitrary string to a readable string, typically for debugging purposes (DebugPrint ...)
2693 ''' Carriage Returns are replaced by \r. Other line breaks are replaced by \n
2694 ''' Tabs are replaced by \t
2695 ''' Backslashes are doubled
2696 ''' Other non printable characters are replaced by \x00 to \xFF or \x0000 to \xFFFF
2697 ''' Args:
2698 ''' pvString: the string to make readable
2699 ''' Return:
2700 ''' the converted string
2702 Dim sString As String
' Return value
2703 Dim sChar As String
' A single character
2704 Dim lAsc As Long
' Ascii value
2705 Dim lPos As Long
' Position in sString
2708 ' Process TABs, CRs and LFs
2709 sString = Replace(Replace(Replace(pvString,
"\
",
"\\
"), SF_String.sfCR,
"\r
"), SF_String.sfTAB,
"\t
")
2710 sString = Join(SF_String.SplitLines(sString, KeepBreaks := False),
"\n
")
2711 ' Process not printable characters
2712 If Len(sString)
> 0 Then
2714 Do While lPos
<= Len(sString)
2715 sChar = Mid(sString, lPos,
1)
2716 If Not SF_String.IsPrintable(sChar) Then
2718 sChar =
"\x
" & Iif(lAsc
< 255, Right(
"00" & Hex(lAsc),
2), Right(
"0000" & Hex(lAsc),
4))
2719 If lPos
< Len(sString) Then
2720 sString = Left(sString, lPos -
1)
& sChar
& Mid(sString, lPos +
1)
2722 sString = Left(sString, lPos -
1)
& sChar
2725 lPos = lPos + Len(sChar)
2731 End Function
' ScriptForge.SF_String._Repr
2733 REM ================================================ END OF SCRIPTFORGE.SF_STRING