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
39 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
40 ''' Some references:
41 ''' https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1i18n_1_1KCharacterType.html
42 ''' com.sun.star.i18n.KCharacterType.###
43 ''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1i18n_1_1XCharacterClassification.html
44 ''' com.sun.star.i18n.XCharacterClassification
46 REM ============================================================ MODULE CONSTANTS
48 ''' Most expressions below are derived from https://www.regular-expressions.info/
50 Const REGEXALPHA =
"^[A-Za-z]+$
" ' Not used
51 Const REGEXALPHANUM =
"^[\w]+$
"
52 Const REGEXDATEDAY =
"(
0[
1-
9]|[
12][
0-
9]|
3[
01])
"
53 Const REGEXDATEMONTH =
"(
0[
1-
9]|
1[
012])
"
54 Const REGEXDATEYEAR =
"(
19|
20)\d\d
"
55 Const REGEXTIMEHOUR =
"(
0[
1-
9]|
1[
0-
9]|
2[
0123])
"
56 Const REGEXTIMEMIN =
"([
0-
5][
0-
9])
"
57 Const REGEXTIMESEC = REGEXTIMEMIN
58 Const REGEXDIGITS =
"^[
0-
9]+$
"
59 Const REGEXEMAIL =
"^[A-Z0-
9._%+-]+@[A-Z0-
9.-]+\.[A-Z]{
2,}$
"
60 Const REGEXFILELINUX =
"^[^
<>:;,?
""*|\\]+$
"
61 Const REGEXFILEWIN =
"^([A-Z]|[a-z]:)?[^
<>:;,?
""*|]+$
"
62 Const REGEXHEXA =
"^(
0X|
&H)?[
0-
9A-F]+$
" ' Includes
0xFF and
&HFF
63 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]?)$
"
64 Const REGEXNUMBER =
"^[-+]?(([
0-
9]+)?\.)?[
0-
9]+([eE][-+]?[
0-
9]+)?$
"
65 Const REGEXURL =
"^(https?|ftp)://[^\s/$.?#].[^\s]*$
"
66 Const REGEXWHITESPACES =
"^[\s]+$
"
67 Const REGEXLTRIM =
"^[\s]+
"
68 Const REGEXRTRIM =
"[\s]+$
"
69 Const REGEXSPACES =
"[\s]+
"
71 ''' Accented characters substitution: https://docs.google.com/spreadsheets/d/
1pJKSueZK8RkAcJFQIiKpYUamWSC1u1xVQchK7Z7BIwc/edit#gid=
0
72 ''' (Many of them are in the list, but do not consider the list as closed vs. the Unicode database)
74 Const cstCHARSWITHACCENT =
"ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðñòóôõöùúûüýÿŠšŸŽž
" _
75 & "ĂăĐđĨĩŨũƠơƯưẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹ₫
"
76 Const cstCHARSWITHOUTACCENT =
"AAAAAACEEEEIIIIDNOOOOOUUUUYaaaaaaceeeeiiiidnooooouuuuyySsYZz
" _
77 & "AaDdIiUuOoUuAaAaAaAaAaAaAaAaAaAaAaAaEeEeEeEeEeEeEeEeIiIiOoOoOoOoOoOoOoOoOoOoOoOoUuUuUuUuUuUuUuYyYyYyYyd
"
79 REM ===================================================== CONSTRUCTOR/DESTRUCTOR
81 REM -----------------------------------------------------------------------------
82 Public Function Dispose() As Variant
84 End Function
' ScriptForge.SF_String Explicit destructor
86 REM ================================================================== PROPERTIES
88 REM -----------------------------------------------------------------------------
89 Property Get CHARSWITHACCENT() As String
90 ''' Latin accents
91 CHARSWITHACCENT = cstCHARSWITHACCENT
92 End Property
' ScriptForge.SF_String.CHARSWITHACCENT
94 REM -----------------------------------------------------------------------------
95 Property Get CHARSWITHOUTACCENT() As String
96 ''' Latin accents
97 CHARSWITHOUTACCENT = cstCHARSWITHOUTACCENT
98 End Property
' ScriptForge.SF_String.CHARSWITHOUTACCENT
100 ''' Symbolic constants for linebreaks
101 REM -----------------------------------------------------------------------------
102 Property Get sfCR() As Variant
103 ''' Carriage return
105 End Property
' ScriptForge.SF_String.sfCR
107 REM -----------------------------------------------------------------------------
108 Property Get sfCRLF() As Variant
109 ''' Carriage return
110 sfCRLF = Chr(
13)
& Chr(
10)
111 End Property
' ScriptForge.SF_String.sfCRLF
113 REM -----------------------------------------------------------------------------
114 Property Get sfLF() As Variant
115 ''' Linefeed
117 End Property
' ScriptForge.SF_String.sfLF
119 REM -----------------------------------------------------------------------------
120 Property Get sfNEWLINE() As Variant
121 ''' Linefeed or Carriage return + Linefeed
122 sfNEWLINE = Iif(GetGuiType() =
1, Chr(
13),
"")
& Chr(
10)
123 End Property
' ScriptForge.SF_String.sfNEWLINE
125 REM -----------------------------------------------------------------------------
126 Property Get sfTAB() As Variant
127 ''' Horizontal tabulation
129 End Property
' ScriptForge.SF_String.sfTAB
131 REM -----------------------------------------------------------------------------
132 Property Get ObjectType As String
133 ''' Only to enable object representation
134 ObjectType =
"SF_String
"
135 End Property
' ScriptForge.SF_String.ObjectType
137 REM -----------------------------------------------------------------------------
138 Property Get ServiceName As String
139 ''' Internal use
140 ServiceName =
"ScriptForge.String
"
141 End Property
' ScriptForge.SF_String.ServiceName
143 REM ============================================================== PUBLIC METHODS
145 REM -----------------------------------------------------------------------------
146 Public Function Capitalize(Optional ByRef InputStr As Variant) As String
147 ''' Return the input string with the
1st character of each word in title case
148 ''' Args:
149 ''' InputStr: the input string
150 ''' Returns:
151 ''' The input string with the
1st character of each word in title case
152 ''' Examples:
153 ''' SF_String.Capitalize(
"this is a title for jean-pierre
") returns
"This Is A Title For Jean-Pierre
"
155 Dim sCapital As String
' Return value
156 Dim lLength As Long
' Length of input string
157 Dim oLocale As Object
' com.sun.star.lang.Locale
158 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
159 Const cstThisSub =
"String.Capitalize
"
160 Const cstSubArgs =
"InputStr
"
162 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
163 sCapital =
""
166 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
167 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
171 lLength = Len(InputStr)
172 If lLength
> 0 Then
173 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
174 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
175 sCapital = oChar.toTitle(InputStr,
0, lLength *
4, oLocale)
' length *
4 because length is expressed in bytes
179 Capitalize = sCapital
180 SF_Utils._ExitFunction(cstThisSub)
184 End Function
' ScriptForge.SF_String.Capitalize
186 REM -----------------------------------------------------------------------------
187 Public Function Count(Optional ByRef InputStr As Variant _
188 , Optional ByVal Substring As Variant _
189 , Optional ByRef IsRegex As Variant _
190 , Optional ByVal CaseSensitive As Variant _
192 ''' Counts the number of occurrences of a substring or a regular expression within a string
193 ''' Args:
194 ''' InputStr: the input stringto examine
195 ''' Substring: the substring to identify
196 ''' IsRegex: True if Substring is a regular expression (default = False)
197 ''' CaseSensitive: default = False
198 ''' Returns:
199 ''' The number of occurrences as a Long
200 ''' Examples:
201 ''' SF_String.Count(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"\b[a-z]+\b
", IsRegex := True, CaseSensitive := True)
202 ''' returns
7 (the number of words in lower case)
203 ''' SF_String.Count(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"or
", CaseSensitive := False)
204 ''' returns
2
207 Dim lOccurrences As Long
' Return value
208 Dim lStart As Long
' Start index of search
209 Dim sSubstring As String
' Substring to replace
210 Dim iCaseSensitive As Integer
' Integer alias for boolean CaseSensitive
211 Const cstThisSub =
"String.Count
"
212 Const cstSubArgs =
"InputStr, Substring, [IsRegex=False], [CaseSensitive=False]
"
214 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
218 If IsMissing(IsRegex) Or IsEmpty(IsRegex) Then IsRegex = False
219 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
220 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
221 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
222 If Not SF_Utils._Validate(Substring,
"Substring
", V_STRING) Then GoTo Finally
223 If Not SF_Utils._Validate(IsRegex,
"IsRegex
", V_BOOLEAN) Then GoTo Finally
224 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
228 iCaseSensitive = Iif(CaseSensitive,
0,
1)
' 1 = False ;)
231 Do While lStart
>=
1 And lStart
<= Len(InputStr)
233 Case False
' Use InStr
234 lStart = InStr(lStart, InputStr, Substring, iCaseSensitive)
235 If lStart =
0 Then Exit Do
236 lStart = lStart + Len(Substring)
237 Case True
' Use FindRegex
238 sSubstring = SF_String.FindRegex(InputStr, Substring, lStart, CaseSensitive)
239 If lStart =
0 Then Exit Do
240 lStart = lStart + Len(sSubstring)
242 lOccurrences = lOccurrences +
1
247 SF_Utils._ExitFunction(cstThisSub)
251 End Function
' ScriptForge.SF_String.Count
253 REM -----------------------------------------------------------------------------
254 Public Function EndsWith(Optional ByRef InputStr As Variant _
255 , Optional ByVal Substring As Variant _
256 , Optional ByVal CaseSensitive As Variant _
258 ''' Returns True if the last characters of InputStr are identical to Substring
259 ''' Args:
260 ''' InputStr: the input string
261 ''' Substring: the suffixing characters
262 ''' CaseSensitive: default = False
263 ''' Returns:
264 ''' True if the comparison is satisfactory
265 ''' False if either InputStr or Substring have a length =
0
266 ''' False if Substr is longer than InputStr
267 ''' Examples:
268 ''' SF_String.EndsWith(
"abcdefg
",
"EFG
") returns True
269 ''' SF_String.EndsWith(
"abcdefg
",
"EFG
", CaseSensitive := True) returns False
271 Dim bEndsWith As Boolean
' Return value
272 Dim lSub As Long
' Length of SUbstring
273 Const cstThisSub =
"String.EndsWith
"
274 Const cstSubArgs =
"InputStr, Substring, [CaseSensitive=False]
"
276 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
280 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
281 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
282 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
283 If Not SF_Utils._Validate(Substring,
"Substring
", V_STRING) Then GoTo Finally
284 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
288 lSub = Len(Substring)
289 If Len(InputStr)
> 0 And lSub
> 0 And lSub
<= Len(InputStr) Then
290 bEndsWith = ( StrComp(Right(InputStr, lSub), Substring, Iif(CaseSensitive,
1,
0)) =
0 )
295 SF_Utils._ExitFunction(cstThisSub)
299 End Function
' ScriptForge.SF_String.EndsWith
301 REM -----------------------------------------------------------------------------
302 Public Function Escape(Optional ByRef InputStr As Variant) As String
303 ''' Convert any hard line breaks or tabs by their escaped equivalent
304 ''' Args:
305 ''' InputStr: the input string
306 ''' Returns:
307 ''' The input string after replacement of
"\
", Chr(
10), Chr(
13), Chr(
9)characters
308 ''' Examples:
309 ''' SF_String.Escape(
"abc
" & Chr(
10)
& Chr(
9)
& "def\n
") returns
"abc\n\tdef\\n
"
311 Dim sEscape As String
' Return value
312 Const cstThisSub =
"String.Escape
"
313 Const cstSubArgs =
"InputStr
"
315 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
316 sEscape =
""
319 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
320 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
324 sEscape = SF_String.ReplaceStr( InputStr _
325 , Array(
"\
", SF_String.sfLF, SF_String.sfCR, SF_String.sfTAB) _
326 , Array(
"\\
",
"\n
",
"\r
",
"\t
") _
331 SF_Utils._ExitFunction(cstThisSub)
335 End Function
' ScriptForge.SF_String.Escape
337 REM -----------------------------------------------------------------------------
338 Public Function ExpandTabs(Optional ByRef InputStr As Variant _
339 , Optional ByVal TabSize As Variant _
341 ''' Return the input string with each TAB (Chr(
9)) character replaced by the adequate number of spaces
342 ''' Args:
343 ''' InputStr: the input string
344 ''' TabSize: defines the TAB positions at TabSize +
1,
2 * TabSize +
1 , ... N * TabSize +
1
345 ''' Default =
8
346 ''' Returns:
347 ''' The input string with spaces replacing the TAB characters
348 ''' If the input string contains line breaks, the TAB positions are reset
349 ''' Examples:
350 ''' SF_String.ExpandTabs(
"abc
" & SF_String.sfTAB
& SF_String.sfTAB
& "def
",
4) returns
"abc def
"
351 ''' SF_String.ExpandTabs(
"abc
" & SF_String.sfTAB
& "def
" & SF_String.sfLF
& SF_String.sfTAB
& "ghi
")
352 ''' returns
"abc def
" & SF_String.sfLF
& " ghi
"
354 Dim sExpanded As String
' Return value
355 Dim lCharPosition As Long
' Position of current character in current line in expanded string
356 Dim lSpaces As Long
' Spaces counter
357 Dim sChar As String
' A single character
360 Const cstThisSub =
"String.ExpandTabs
"
361 Const cstSubArgs =
"InputStr, [TabSize=
8]
"
363 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
364 sExpanded =
""
367 If IsMissing(TabSize) Or IsEmpty(TabSize) Then TabSize = cstTabSize
368 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
369 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
370 If Not SF_Utils._Validate(TabSize,
"TabSize
", V_NUMERIC) Then GoTo Finally
372 If TabSize
<=
0 Then TabSize = cstTabSize
376 If Len(InputStr)
> 0 Then
377 For i =
1 To Len(InputStr)
378 sChar = Mid(InputStr, i,
1)
380 Case SF_String.sfLF, Chr(
12), SF_String.sfCR, Chr(
28), Chr(
29), Chr(
30), Chr(
133), Chr(
8232), Chr(
8233)
381 sExpanded = sExpanded
& sChar
384 lSpaces = Int(lCharPosition / TabSize +
1) * TabSize - lCharPosition
385 sExpanded = sExpanded
& Space(lSpaces)
386 lCharPosition = lCharPosition + lSpaces
388 sExpanded = sExpanded
& sChar
389 lCharPosition = lCharPosition +
1
395 ExpandTabs = sExpanded
396 SF_Utils._ExitFunction(cstThisSub)
400 End Function
' ScriptForge.SF_String.ExpandTabs
402 REM -----------------------------------------------------------------------------
403 Public Function FilterNotPrintable(Optional ByRef InputStr As Variant _
404 , Optional ByVal ReplacedBy As Variant _
406 ''' Return the input string in which all the not printable characters are replaced by ReplacedBy
407 ''' Among others, control characters (Ascii
<=
1F) are not printable
408 ''' Args:
409 ''' InputStr: the input string
410 ''' ReplacedBy: zero, one or more characters replacing the found not printable characters
411 ''' Default = the zero-length string
412 ''' Returns:
413 ''' The input string in which all the not printable characters are replaced by ReplacedBy
414 ''' Examples:
415 ''' SF_String.FilterNotPrintable(
"àén ΣlPµ
" & Chr(
10)
& " Русский
",
"\n
") returns
"àén ΣlPµ\n Русский
"
417 Dim sPrintable As String
' Return value
418 Dim bPrintable As Boolean
' Is a single character printable ?
419 Dim lLength As Long
' Length of InputStr
420 Dim lReplace As Long
' Length of ReplacedBy
421 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
422 Dim oLocale As Object
' com.sun.star.lang.Locale
423 Dim lType As Long
' com.sun.star.i18n.KCharacterType
424 Dim sChar As String
' A single character
425 Dim lPRINTABLE As Long : lPRINTABLE = com.sun.star.i18n.KCharacterType.PRINTABLE
427 Const cstThisSub =
"String.FilterNotPrintable
"
428 Const cstSubArgs =
"InputStr, [ReplacedBy=
""""]
"
430 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
431 sPrintable =
""
434 If IsMissing(ReplacedBy) Or IsEmpty(ReplacedBy) Then ReplacedBy =
""
435 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
436 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
437 If Not SF_Utils._Validate(ReplacedBy,
"ReplacedBy
", V_STRING) Then GoTo Finally
441 lLength = Len(InputStr)
442 lReplace = Len(ReplacedBy)
443 If lLength
> 0 Then
444 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
445 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
446 For i =
0 To lLength -
1
447 sChar = Mid(InputStr, i +
1,
1)
448 lType = oChar.getCharacterType(sChar,
0, oLocale)
449 ' Parenthses (), [], {} have a KCharacterType =
0
450 bPrintable = ( (lType And lPRINTABLE) = lPRINTABLE Or (lType =
0 And Asc(sChar)
<=
127) )
451 If Not bPrintable Then
452 If lReplace
> 0 Then sPrintable = sPrintable
& ReplacedBy
454 sPrintable = sPrintable
& sChar
460 FilterNotPrintable = sPrintable
461 SF_Utils._ExitFunction(cstThisSub)
465 End Function
' ScriptForge.SF_String.FilterNotPrintable
467 REM -----------------------------------------------------------------------------
468 Public Function FindRegex(Optional ByRef InputStr As Variant _
469 , Optional ByVal Regex As Variant _
470 , Optional ByRef Start As Variant _
471 , Optional ByVal CaseSensitive As Variant _
472 , Optional ByVal Forward As Variant _
474 ''' Find in InputStr a substring matching a given regular expression
475 ''' Args:
476 ''' InputStr: the input string to be searched for the expression
477 ''' Regex: the regular expression
478 ''' Start (passed by reference): where to start searching from
479 ''' Should be =
1 (Forward = True) or = Len(InputStr) (Forward = False) the
1st time
480 ''' After execution points to the first character of the found substring
481 ''' CaseSensitive: default = False
482 ''' Forward: True (default) or False (backward)
483 ''' Returns:
484 ''' The found substring matching the regular expression
485 ''' A zero-length string if not found (Start is set to
0)
486 ''' Examples:
487 ''' Dim lStart As Long : lStart =
1
488 ''' SF_String.FindRegex(
"abCcdefghHij
",
"C.*H
", lStart, CaseSensitive := True) returns
"CcdefghH
"
489 ''' Above statement may be reexecuted for searching the same or another pattern
490 ''' by starting from lStart + Len(matching string)
492 Dim sOutput As String
' Return value
493 Dim oTextSearch As Object
' com.sun.star.util.TextSearch
494 Dim vOptions As Variant
' com.sun.star.util.SearchOptions
495 Dim lEnd As Long
' Upper limit of search area
496 Dim vResult As Object
' com.sun.star.util.SearchResult
497 Const cstThisSub =
"String.FindRegex
"
498 Const cstSubArgs =
"InputStr, Regex, [Start=
1], [CaseSensitive=False], [Forward=True]
"
500 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
501 sOutput =
""
504 If IsMissing(Start) Or IsEmpty(Start) Then Start =
1
505 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
506 If IsMissing(Forward) Or IsEmpty(Forward) Then Forward = True
507 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
508 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
509 If Not SF_Utils._Validate(Regex,
"Regex
", V_STRING) Then GoTo Finally
510 If Not SF_Utils._Validate(Start,
"Start
", V_NUMERIC) Then GoTo Finally
511 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
512 If Not SF_Utils._Validate(Forward,
"Forward
", V_BOOLEAN) Then GoTo Finally
514 If Start
<=
0 Or Start
> Len(InputStr) Then GoTo Finally
517 sOutput =
""
518 Set oTextSearch = SF_Utils._GetUNOService(
"TextSearch
")
519 ' Set pattern search options
520 vOptions = SF_Utils._GetUNOService(
"SearchOptions
")
522 .searchString = Regex
523 If CaseSensitive Then .transliterateFlags =
0 Else .transliterateFlags = com.sun.star.i18n.TransliterationModules.IGNORE_CASE
527 .setOptions(vOptions)
530 vResult = .searchForward(InputStr, Start -
1, lEnd)
533 vResult = .searchBackward(InputStr, Start, lEnd -
1)
536 ' https://api.libreoffice.org/docs/idl/ref/structcom_1_1sun_1_1star_1_1util_1_1SearchResult.html
538 If .subRegExpressions
>=
1 Then
540 Start = .startOffset(
0) +
1
541 lEnd = .endOffset(
0) +
1
543 Start = .endOffset(
0) +
1
544 lEnd = .startOffset(
0) +
1
546 sOutput = Mid(InputStr, Start, lEnd - Start)
554 SF_Utils._ExitFunction(cstThisSub)
558 End Function
' ScriptForge.SF_String.FindRegex
560 REM -----------------------------------------------------------------------------
561 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
562 ''' Return the actual value of the given property
563 ''' Args:
564 ''' PropertyName: the name of the property as a string
565 ''' Returns:
566 ''' The actual value of the property
567 ''' Exceptions
568 ''' ARGUMENTERROR The property does not exist
570 Const cstThisSub =
"String.GetProperty
"
571 Const cstSubArgs =
"PropertyName
"
573 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
577 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
578 If Not SF_Utils._Validate(PropertyName,
"PropertyName
", V_STRING, Properties()) Then GoTo Catch
582 Select Case UCase(PropertyName)
583 Case
"SFCR
" : GetProperty = sfCR
584 Case
"SFCRLF
" : GetProperty = sfCRLF
585 Case
"SFLF
" : GetProperty = sfLF
586 Case
"SFNEWLINE
" : GetProperty = sfNEWLINE
587 Case
"SFTAB
" : GetProperty = sfTAB
592 SF_Utils._ExitFunction(cstThisSub)
596 End Function
' ScriptForge.SF_String.GetProperty
598 REM -----------------------------------------------------------------------------
599 Public Function HashStr(Optional ByVal InputStr As Variant _
600 , Optional ByVal Algorithm As Variant _
602 ''' Return an hexadecimal string representing a checksum of the given input string
603 ''' Next algorithms are supported: MD5, SHA1, SHA224, SHA256, SHA384 and SHA512
604 ''' Args:
605 ''' InputStr: the string to be hashed
606 ''' Algorithm: The hashing algorithm to use
607 ''' Returns:
608 ''' The requested checksum as a string. Hexadecimal digits are lower-cased
609 ''' A zero-length string when an error occurred
610 ''' Example:
611 ''' Print SF_String.HashStr(
"œ∑¡™£¢∞§¶•ªº–≠œ∑´®†¥¨ˆøπ“‘åß∂ƒ©˙∆˚¬
",
"MD5
")
' 616eb9c513ad07cd02924b4d285b9987
613 Dim sHash As String
' Return value
614 Const cstPyHelper =
"$
" & "_SF_String__HashStr
"
615 Const cstThisSub =
"String.HashStr
"
616 Const cstSubArgs =
"InputStr, Algorithm=
""MD5
""|
""SHA1
""|
""SHA224
""|
""SHA256
""|
""SHA384
""|
""SHA512
"""
618 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
622 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
623 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
624 If Not SF_Utils._Validate(Algorithm,
"Algorithm
", V_STRING _
625 , Array(
"MD5
",
"SHA1
",
"SHA224
",
"SHA256
",
"SHA384
",
"SHA512
")) Then GoTo Finally
629 With ScriptForge.SF_Session
630 sHash = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper
& cstPyHelper _
631 , InputStr, LCase(Algorithm))
636 SF_Utils._ExitFunction(cstThisSub)
640 End Function
' ScriptForge.SF_String.HashStr
642 REM -----------------------------------------------------------------------------
643 Public Function HtmlEncode(Optional ByRef InputStr As Variant) As String
644 ''' &-encoding of the input string (e.g.
"é
" becomes
"&eacute;
" or numeric equivalent
645 ''' Args:
646 ''' InputStr: the input string
647 ''' Returns:
648 ''' the encoded string
649 ''' Examples:
650 ''' SF_String.HtmlEncode(
"<a href=
""https://a.b.com
"">From α to ω
</a
>")
651 ''' returns
"&lt;a href=
&quot;https://a.b.com
&quot;
&gt;From
&#
945; to
&#
969;
&lt;/a
&gt;
"
653 Dim sEncode As String
' Return value
654 Dim lPos As Long
' Position in InputStr
655 Dim sChar As String
' A single character extracted from InputStr
657 Const cstThisSub =
"String.HtmlEncode
"
658 Const cstSubArgs =
"InputStr
"
660 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
661 sEncode =
""
664 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
665 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
669 If Len(InputStr)
> 0 Then
672 Do While lPos
<= Len(sEncode)
673 sChar = Mid(sEncode, lPos,
1)
674 ' Leave as is or encode every single char
676 Case
"""" : sChar =
"&quot;
"
677 Case
"&" : sChar =
"&amp;
"
678 Case
"<" : sChar =
"&lt;
"
679 Case
">" : sChar =
"&gt;
"
680 Case
"'" : sChar =
"&apos;
"
681 Case
":
",
"/
",
"?
",
"#
",
"[
",
"]
",
"@
" ' Reserved characters
682 Case SF_String.sfCR : sChar =
"" ' Carriage return
683 Case SF_String.sfLF : sChar =
"<br
>" ' Line Feed
685 Case
"€
" : sChar =
"&euro;
"
686 Case Else : sChar =
"&#
" & Asc(sChar)
& ";
"
688 If Len(sChar) =
1 Then
689 Mid(sEncode, lPos,
1) = sChar
691 sEncode = Left(sEncode, lPos -
1)
& sChar
& Mid(sEncode, lPos +
1)
693 lPos = lPos + Len(sChar)
699 SF_Utils._ExitFunction(cstThisSub)
703 End Function
' ScriptForge.SF_String.HtmlEncode
705 REM -----------------------------------------------------------------------------
706 Public Function IsADate(Optional ByRef InputStr As Variant _
707 , Optional ByVal DateFormat _
709 ''' Return True if the string is a valid date respecting the given format
710 ''' Args:
711 ''' InputStr: the input string
712 ''' DateFormat: either YYYY-MM-DD (default), DD-MM-YYYY or MM-DD-YYYY
713 ''' The dash (-) may be replaced by a dot (.), a slash (/) or a space
714 ''' Returns:
715 ''' True if the string contains a valid date and there is at least one character
716 ''' False otherwise or if the date format is invalid
717 ''' Examples:
718 ''' SF_String.IsADate(
"2019-
12-
31",
"YYYY-MM-DD
") returns True
720 Dim bADate As Boolean
' Return value
721 Dim sFormat As String
' Alias for DateFormat
722 Dim sRegex As String
' The regex to check against the input string
723 Const cstFormat =
"YYYY-MM-DD
" ' Default date format
724 Const cstFormatRegex =
"(YYYY[- /.]MM[- /.]DD|MM[- /.]DD[- /.]YYYY|DD[- /.]MM[- /.]YYYY)
"
725 ' The regular expression the format must match
726 Const cstThisSub =
"String.IsADate
"
727 Const cstSubArgs =
"InputStr, [DateFormat=
""" & cstFormat
& """]
"
729 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
733 If IsMissing(DateFormat) Or IsEmpty(DateFormat) Then DateFormat =
"YYYY-MM-DD
"
734 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
735 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
736 If Not SF_Utils._Validate(DateFormat,
"DateFormat
", V_STRING) Then GoTo Finally
738 sFormat = UCase(DateFormat)
739 If Len(sFormat)
<> Len(cstFormat)Then GoTo Finally
740 If sFormat
<> cstFormat Then
' Do not check if default format
741 If Not SF_String.IsRegex(sFormat, cstFormatRegex) Then GoTo Finally
745 If Len(InputStr) = Len(DateFormat) Then
746 sRegex = ReplaceStr(sFormat, Array(
"YYYY
",
"MM
",
"DD
") _
747 , Array(REGEXDATEYEAR, REGEXDATEMONTH, REGEXDATEDAY) _
748 , CaseSensitive := False)
749 bADate = SF_String.IsRegex(InputStr, sRegex, CaseSensitive := False)
754 SF_Utils._ExitFunction(cstThisSub)
758 End Function
' ScriptForge.SF_String.IsADate
760 REM -----------------------------------------------------------------------------
761 Public Function IsAlpha(Optional ByRef InputStr As Variant) As Boolean
762 ''' Return True if all characters in the string are alphabetic
763 ''' Alphabetic characters are those characters defined in the Unicode character database as “Letter”
764 ''' Args:
765 ''' InputStr: the input string
766 ''' Returns:
767 ''' True if the string is alphabetic and there is at least one character, False otherwise
768 ''' Examples:
769 ''' SF_String.IsAlpha(
"àénΣlPµ
") returns True
770 ''' Note:
771 ''' Use SF_String.IsRegex(
"...
", REGEXALPHA) to limit characters to latin alphabet
773 Dim bAlpha As Boolean
' Return value
774 Dim lLength As Long
' Length of InputStr
775 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
776 Dim oLocale As Object
' com.sun.star.lang.Locale
777 Dim lType As Long
' com.sun.star.i18n.KCharacterType
778 Dim lLETTER As Long : lLETTER = com.sun.star.i18n.KCharacterType.LETTER
780 Const cstThisSub =
"String.IsAlpha
"
781 Const cstSubArgs =
"InputStr
"
783 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
787 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
788 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
792 lLength = Len(InputStr)
793 If lLength
> 0 Then
794 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
795 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
796 For i =
0 To lLength -
1
797 lType = oChar.getCharacterType(InputStr, i, oLocale)
798 bAlpha = ( (lType And lLETTER) = lLETTER )
799 If Not bAlpha Then Exit For
805 SF_Utils._ExitFunction(cstThisSub)
809 End Function
' ScriptForge.SF_String.IsAlpha
811 REM -----------------------------------------------------------------------------
812 Public Function IsAlphaNum(Optional ByRef InputStr As Variant) As Boolean
813 ''' Return True if all characters in the string are alphabetic, digits or
"_
" (underscore)
814 ''' The first character must not be a digit
815 ''' Args:
816 ''' InputStr: the input string
817 ''' Returns:
818 ''' True if the string is alphanumeric and there is at least one character, False otherwise
819 ''' Examples:
820 ''' SF_String.IsAlphaNum(
"_ABC_123456_abcàénΣlPµ
") returns True
822 Dim bAlphaNum As Boolean
' Return value
823 Dim sInputStr As String
' Alias of InputStr without underscores
824 Dim sFirst As String
' Leftmost character of InputStr
825 Dim lLength As Long
' Length of InputStr
826 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
827 Dim oLocale As Object
' com.sun.star.lang.Locale
828 Dim lType As Long
' com.sun.star.i18n.KCharacterType
829 Dim lLETTER As Long : lLETTER = com.sun.star.i18n.KCharacterType.LETTER
830 Dim lDIGIT As Long : lDIGIT = com.sun.star.i18n.KCharacterType.DIGIT
832 Const cstThisSub =
"String.IsAlphaNum
"
833 Const cstSubArgs =
"InputStr
"
835 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
839 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
840 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
844 lLength = Len(InputStr)
845 If lLength
> 0 Then
846 sFirst = Left(InputStr,
1)
847 bAlphanum = ( sFirst
< "0" Or sFirst
> "9" )
849 sInputStr = Replace(InputStr,
"_
",
"A
")
' Replace by an arbitrary alphabetic character
850 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
851 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
852 For i =
0 To lLength -
1
853 lType = oChar.getCharacterType(sInputStr, i, oLocale)
854 bAlphaNum = ( (lType And lLETTER) = lLETTER _
855 Or (lType And lDIGIT) = lDIGIT )
856 If Not bAlphaNum Then Exit For
862 IsAlphaNum = bAlphaNum
863 SF_Utils._ExitFunction(cstThisSub)
867 End Function
' ScriptForge.SF_String.IsAlphaNum
869 REM -----------------------------------------------------------------------------
870 Public Function IsAscii(Optional ByRef InputStr As Variant) As Boolean
871 ''' Return True if all characters in the string are Ascii characters
872 ''' Ascii characters are those characters defined between
&H00 and
&H7F
873 ''' Args:
874 ''' InputStr: the input string
875 ''' Returns:
876 ''' True if the string is Ascii and there is at least one character, False otherwise
877 ''' Examples:
878 ''' SF_String.IsAscii(
"a%?,
25") returns True
880 Dim bAscii As Boolean
' Return value
881 Dim lLength As Long
' Length of InputStr
882 Dim sChar As String
' Single character
884 Const cstThisSub =
"String.IsAscii
"
885 Const cstSubArgs =
"InputStr
"
887 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
891 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
892 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
896 lLength = Len(InputStr)
897 If lLength
> 0 Then
899 sChar = Mid(InputStr, i,
1)
900 bAscii = ( Asc(sChar)
<=
127 )
901 If Not bAscii Then Exit For
907 SF_Utils._ExitFunction(cstThisSub)
911 End Function
' ScriptForge.SF_String.IsAscii
913 REM -----------------------------------------------------------------------------
914 Public Function IsDigit(Optional ByRef InputStr As Variant) As Boolean
915 ''' Return True if all characters in the string are digits
916 ''' Args:
917 ''' InputStr: the input string
918 ''' Returns:
919 ''' True if the string contains only digits and there is at least one character, False otherwise
920 ''' Examples:
921 ''' SF_String.IsDigit(
"123456") returns True
923 Dim bDigit As Boolean
' Return value
924 Const cstThisSub =
"String.IsDigit
"
925 Const cstSubArgs =
"InputStr
"
927 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
931 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
932 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
936 If Len(InputStr)
> 0 Then bDigit = SF_String.IsRegex(InputStr, REGEXDIGITS, CaseSensitive := False)
940 SF_Utils._ExitFunction(cstThisSub)
944 End Function
' ScriptForge.SF_String.IsDigit
946 REM -----------------------------------------------------------------------------
947 Public Function IsEmail(Optional ByRef InputStr As Variant) As Boolean
948 ''' Return True if the string is a valid email address
949 ''' Args:
950 ''' InputStr: the input string
951 ''' Returns:
952 ''' True if the string contains an email address and there is at least one character, False otherwise
953 ''' Examples:
954 ''' SF_String.IsEmail(
"first.last@something.org
") returns True
956 Dim bEmail As Boolean
' Return value
957 Const cstThisSub =
"String.IsEmail
"
958 Const cstSubArgs =
"InputStr
"
960 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
964 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
965 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
969 If Len(InputStr)
> 0 Then bEmail = SF_String.IsRegex(InputStr, REGEXEMAIL, CaseSensitive := False)
973 SF_Utils._ExitFunction(cstThisSub)
977 End Function
' ScriptForge.SF_String.IsEmail
979 REM -----------------------------------------------------------------------------
980 Public Function IsFileName(Optional ByRef InputStr As Variant _
981 , Optional ByVal OSName As Variant _
983 ''' Return True if the string is a valid filename in a given operating system
984 ''' Args:
985 ''' InputStr: the input string
986 ''' OSName: Windows, Linux, macOS or Solaris
987 ''' The default is the current operating system on which the script is run
988 ''' Returns:
989 ''' True if the string contains a valid filename and there is at least one character, False otherwise
990 ''' Examples:
991 ''' SF_String.IsFileName(
"/home/a file name.odt
",
"LINUX
") returns True
993 Dim bFileName As Boolean
' Return value
994 Dim sRegex As String
' Regex to apply depending on OS
995 Const cstThisSub =
"String.IsFileName
"
996 Const cstSubArgs =
"InputStr, [OSName=
""Windows
""|
""Linux
""|
""macOS
""|Solaris
""]
"
998 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1002 If IsMissing(OSName) Or IsEmpty(OSName) Then
1003 If _SF_.OSname =
"" Then _SF_.OSName = SF_Platform.OSName
1004 OSName = _SF_.OSName
1006 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1007 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1008 If Not SF_Utils._Validate(OSName,
"OSName
", V_STRING, Array(
"Windows
",
"Linux
",
"macOS
",
"Solaris
")) Then GoTo Finally
1012 If Len(InputStr)
> 0 Then
1013 Select Case UCase(OSName)
1014 Case
"LINUX
",
"MACOS
",
"SOLARIS
" : sRegex = REGEXFILELINUX
1015 Case
"WINDOWS
" : sRegex = REGEXFILEWIN
1017 bFileName = SF_String.IsRegex(InputStr, sRegex, CaseSensitive := False)
1021 IsFileName = bFileName
1022 SF_Utils._ExitFunction(cstThisSub)
1026 End Function
' ScriptForge.SF_String.IsFileName
1028 REM -----------------------------------------------------------------------------
1029 Public Function IsHexDigit(Optional ByRef InputStr As Variant) As Boolean
1030 ''' Return True if all characters in the string are hexadecimal digits
1031 ''' Args:
1032 ''' InputStr: the input string
1033 ''' Returns:
1034 ''' True if the string contains only hexadecimal igits and there is at least one character
1035 ''' The prefixes
"0x
" and
"&H
" are admitted
1036 ''' False otherwise
1037 ''' Examples:
1038 ''' SF_String.IsHexDigit(
"&H00FF
") returns True
1040 Dim bHexDigit As Boolean
' Return value
1041 Const cstThisSub =
"String.IsHexDigit
"
1042 Const cstSubArgs =
"InputStr
"
1044 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1048 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1049 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1053 If Len(InputStr)
> 0 Then bHexDigit = SF_String.IsRegex(InputStr, REGEXHEXA, CaseSensitive := False)
1056 IsHexDigit = bHexDigit
1057 SF_Utils._ExitFunction(cstThisSub)
1061 End Function
' ScriptForge.SF_String.IsHexDigit
1063 REM -----------------------------------------------------------------------------
1064 Public Function IsIPv4(Optional ByRef InputStr As Variant) As Boolean
1065 ''' Return True if the string is a valid IPv4 address
1066 ''' Args:
1067 ''' InputStr: the input string
1068 ''' Returns:
1069 ''' True if the string contains a valid IPv4 address and there is at least one character, False otherwise
1070 ''' Examples:
1071 ''' SF_String.IsIPv4(
"192.168.1.50") returns True
1073 Dim bIPv4 As Boolean
' Return value
1074 Const cstThisSub =
"String.IsIPv4
"
1075 Const cstSubArgs =
"InputStr
"
1077 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1081 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1082 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1086 If Len(InputStr)
> 0 Then bIPv4 = SF_String.IsRegex(InputStr, REGEXIPV4, CaseSensitive := False)
1090 SF_Utils._ExitFunction(cstThisSub)
1094 End Function
' ScriptForge.SF_String.IsIPv4
1096 REM -----------------------------------------------------------------------------
1097 Public Function IsLike(Optional ByRef InputStr As Variant _
1098 , Optional ByVal Pattern As Variant _
1099 , Optional ByVal CaseSensitive As Variant _
1101 ''' Returns True if the whole input string matches a given pattern containing wildcards
1102 ''' Args:
1103 ''' InputStr: the input string
1104 ''' Pattern: the pattern as a string
1105 ''' Admitted wildcard are: the
"?
" represents any single character
1106 ''' the
"*
" represents zero, one, or multiple characters
1107 ''' CaseSensitive: default = False
1108 ''' Returns:
1109 ''' True if a match is found
1110 ''' Zero-length input or pattern strings always return False
1111 ''' Examples:
1112 ''' SF_String.IsLike(
"aAbB
",
"?A*
") returns True
1113 ''' SF_String.IsLike(
"C:\a\b\c\f.odb
",
"?:*.*
") returns True
1115 Dim bLike As Boolean
' Return value
1116 ' Build an equivalent regular expression by escaping the special characters present in Pattern
1117 Dim sRegex As String
' Equivalent regular expression
1118 Const cstSpecialChars =
"\,^,$,.,|,+,(,),[,{,?,*
" ' List of special chars in regular expressions
1119 Const cstEscapedChars =
"\\,\^,\$,\.,\|,\+,\(,\),\[,\{,.,.*
"
1121 Const cstThisSub =
"String.IsLike
"
1122 Const cstSubArgs =
"InputStr, Pattern, [CaseSensitive=False]
"
1124 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1128 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1129 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1130 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1131 If Not SF_Utils._Validate(Pattern,
"Pattern
", V_STRING) Then GoTo Finally
1132 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1136 If Len(InputStr)
> 0 And Len(Pattern)
> 0 Then
1137 ' Substitute special chars by escaped chars
1138 sRegex = SF_String.ReplaceStr(Pattern, Split(cstSPecialChars,
",
"), Split(cstEscapedChars,
",
"))
1139 bLike = SF_String.IsRegex(InputStr, sRegex, CaseSensitive)
1144 SF_Utils._ExitFunction(cstThisSub)
1148 End Function
' ScriptForge.SF_String.IsLike
1150 REM -----------------------------------------------------------------------------
1151 Public Function IsLower(Optional ByRef InputStr As Variant) As Boolean
1152 ''' Return True if all characters in the string are in lower case
1153 ''' Non alphabetic characters are ignored
1154 ''' Args:
1155 ''' InputStr: the input string
1156 ''' Returns:
1157 ''' True if the string contains only lower case characters and there is at least one character, False otherwise
1158 ''' Examples:
1159 ''' SF_String.IsLower(
"abc
'(-xyz
") returns True
1161 Dim bLower As Boolean
' Return value
1162 Const cstThisSub =
"String.IsLower
"
1163 Const cstSubArgs =
"InputStr
"
1165 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1169 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1170 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1174 If Len(InputStr)
> 0 Then bLower = ( StrComp(InputStr, LCase(InputStr),
1) =
0 )
1178 SF_Utils._ExitFunction(cstThisSub)
1182 End Function
' ScriptForge.SF_String.IsLower
1184 REM -----------------------------------------------------------------------------
1185 Public Function IsPrintable(Optional ByRef InputStr As Variant) As Boolean
1186 ''' Return True if all characters in the string are printable
1187 ''' In particular, control characters (Ascii
<=
1F) are not printable
1188 ''' Args:
1189 ''' InputStr: the input string
1190 ''' Returns:
1191 ''' True if the string is printable and there is at least one character, False otherwise
1192 ''' Examples:
1193 ''' SF_String.IsPrintable(
"àén ΣlPµ Русский
") returns True
1195 Dim bPrintable As Boolean
' Return value
1196 Dim lLength As Long
' Length of InputStr
1197 Dim oChar As Object
' com.sun.star.i18n.CharacterClassification
1198 Dim oLocale As Object
' com.sun.star.lang.Locale
1199 Dim lType As Long
' com.sun.star.i18n.KCharacterType
1200 Dim sChar As String
' A single character
1201 Dim lPRINTABLE As Long : lPRINTABLE = com.sun.star.i18n.KCharacterType.PRINTABLE
1203 Const cstThisSub =
"String.IsPrintable
"
1204 Const cstSubArgs =
"InputStr
"
1206 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1210 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1211 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1215 lLength = Len(InputStr)
1216 If lLength
> 0 Then
1217 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
1218 Set oChar = SF_Utils._GetUNOService(
"CharacterClass
")
1219 For i =
0 To lLength -
1
1220 sChar = Mid(InputStr, i +
1,
1)
1221 lType = oChar.getCharacterType(sChar,
0, oLocale)
1222 ' Parenthses (), [], {} have a KCharacterType =
0
1223 bPrintable = ( (lType And lPRINTABLE) = lPRINTABLE Or (lType =
0 And Asc(sChar)
<=
127) )
1224 If Not bPrintable Then Exit For
1229 IsPrintable = bPrintable
1230 SF_Utils._ExitFunction(cstThisSub)
1234 End Function
' ScriptForge.SF_String.IsPrintable
1236 REM -----------------------------------------------------------------------------
1237 Public Function IsRegex(Optional ByRef InputStr As Variant _
1238 , Optional ByVal Regex As Variant _
1239 , Optional ByVal CaseSensitive As Variant _
1241 ''' Returns True if the whole input string matches a given regular expression
1242 ''' Args:
1243 ''' InputStr: the input string
1244 ''' Regex: the regular expression as a string
1245 ''' CaseSensitive: default = False
1246 ''' Returns:
1247 ''' True if a match is found
1248 ''' Zero-length input or regex strings always return False
1249 ''' Examples:
1250 ''' SF_String.IsRegex(
"aAbB
",
"[A-Za-z]+
") returns True
1252 Dim bRegex As Boolean
' Return value
1253 Dim lStart As Long
' Must be
1
1254 Dim sMatch As String
' Matching string
1255 Const cstBegin =
"^
" ' Beginning of line symbol
1256 Const cstEnd =
"$
" ' End of line symbol
1257 Const cstThisSub =
"String.IsRegex
"
1258 Const cstSubArgs =
"InputStr, Regex, [CaseSensitive=False]
"
1260 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1264 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1265 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1266 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1267 If Not SF_Utils._Validate(Regex,
"Regex
", V_STRING) Then GoTo Finally
1268 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1272 If Len(InputStr)
> 0 And Len(Regex)
> 0 Then
1273 ' Whole string must match Regex
1275 If Left(Regex,
1)
<> cstBegin Then Regex = cstBegin
& Regex
1276 If Right(Regex,
1)
<> cstEnd Then Regex = Regex
& cstEnd
1277 sMatch = SF_String.FindRegex(InputStr, Regex, lStart, CaseSensitive)
1279 bRegex = ( lStart =
1 And Len(sMatch) = Len(InputStr) )
1284 SF_Utils._ExitFunction(cstThisSub)
1288 End Function
' ScriptForge.SF_String.IsRegex
1290 REM -----------------------------------------------------------------------------
1291 Public Function IsSheetName(Optional ByRef InputStr As Variant) As Boolean
1292 ''' Return True if the input string can serve as a valid Calc sheet name
1293 ''' The sheet name must not contain the characters [ ] * ? : / \
1294 ''' or the character
' (apostrophe) as first or last character.
1296 ''' Args:
1297 ''' InputStr: the input string
1298 ''' Returns:
1299 ''' True if the string is validated as a potential Calc sheet name, False otherwise
1300 ''' Examples:
1301 ''' SF_String.IsSheetName(
"1àbc +
""def
""") returns True
1303 Dim bSheetName As Boolean
' Return value
1304 Const cstThisSub =
"String.IsSheetName
"
1305 Const cstSubArgs =
"InputStr
"
1307 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1311 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1312 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1316 If Len(InputStr)
> 0 Then
1317 If Left(InputStr,
1) =
"'" Or Right(InputStr,
1) =
"'" Then
1318 ElseIf InStr(InputStr,
"[
") _
1319 + InStr(InputStr,
"]
") _
1320 + InStr(InputStr,
"*
") _
1321 + InStr(InputStr,
"?
") _
1322 + InStr(InputStr,
":
") _
1323 + InStr(InputStr,
"/
") _
1324 + InStr(InputStr,
"\
") _
1331 IsSheetName = bSheetName
1332 SF_Utils._ExitFunction(cstThisSub)
1336 End Function
' ScriptForge.SF_String.IsSheetName
1338 REM -----------------------------------------------------------------------------
1339 Public Function IsTitle(Optional ByRef InputStr As Variant) As Boolean
1340 ''' Return True if the
1st character of every word is in upper case and the other characters are in lower case
1341 ''' Args:
1342 ''' InputStr: the input string
1343 ''' Returns:
1344 ''' True if the string is capitalized and there is at least one character, False otherwise
1345 ''' Examples:
1346 ''' SF_String.IsTitle(
"This Is A Title For Jean-Pierre
") returns True
1348 Dim bTitle As Boolean
' Return value
1349 Const cstThisSub =
"String.IsTitle
"
1350 Const cstSubArgs =
"InputStr
"
1352 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1356 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1357 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1361 If Len(InputStr)
> 0 Then bTitle = ( StrComp(InputStr, SF_String.Capitalize(InputStr),
1) =
0 )
1365 SF_Utils._ExitFunction(cstThisSub)
1369 End Function
' ScriptForge.SF_String.IsTitle
1371 REM -----------------------------------------------------------------------------
1372 Public Function IsUpper(Optional ByRef InputStr As Variant) As Boolean
1373 ''' Return True if all characters in the string are in upper case
1374 ''' Non alphabetic characters are ignored
1375 ''' Args:
1376 ''' InputStr: the input string
1377 ''' Returns:
1378 ''' True if the string contains only upper case characters and there is at least one character, False otherwise
1379 ''' Examples:
1380 ''' SF_String.IsUpper(
"ABC
'(-XYZ
") returns True
1382 Dim bUpper As Boolean
' Return value
1383 Const cstThisSub =
"String.IsUpper
"
1384 Const cstSubArgs =
"InputStr
"
1386 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1390 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1391 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1395 If Len(InputStr)
> 0 Then bUpper = ( StrComp(InputStr, UCase(InputStr),
1) =
0 )
1399 SF_Utils._ExitFunction(cstThisSub)
1403 End Function
' ScriptForge.SF_String.IsUpper
1405 REM -----------------------------------------------------------------------------
1406 Public Function IsUrl(Optional ByRef InputStr As Variant) As Boolean
1407 ''' Return True if the string is a valid absolute URL (Uniform Resource Locator)
1408 ''' The parsing is done by the ParseStrict method of the URLTransformer UNO service
1409 ''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XURLTransformer.html
1410 ''' Args:
1411 ''' InputStr: the input string
1412 ''' Returns:
1413 ''' True if the string contains a URL and there is at least one character, False otherwise
1414 ''' Examples:
1415 ''' SF_String.IsUrl(
"http://foo.bar/?q=Test%
20URL-encoded%
20stuff
") returns True
1417 Dim bUrl As Boolean
' Return value
1418 Const cstThisSub =
"String.IsUrl
"
1419 Const cstSubArgs =
"InputStr
"
1421 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1425 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1426 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1430 If Len(InputStr)
> 0 Then bUrl = ( Len(SF_FileSystem._ParseUrl(InputStr).Main)
> 0 )
1434 SF_Utils._ExitFunction(cstThisSub)
1438 End Function
' ScriptForge.SF_String.IsUrl
1440 REM -----------------------------------------------------------------------------
1441 Public Function IsWhitespace(Optional ByRef InputStr As Variant) As Boolean
1442 ''' Return True if all characters in the string are whitespaces
1443 ''' Whitespaces include Space(
32), HT(
9), LF(
10), VT(
11), FF(
12), CR(
13), Next Line(
133), No-break space(
160),
1444 ''' Line separator(
8232), Paragraph separator(
8233)
1445 ''' Args:
1446 ''' InputStr: the input string
1447 ''' Returns:
1448 ''' True if the string contains only whitespaces and there is at least one character, False otherwise
1449 ''' Examples:
1450 ''' SF_String.IsWhitespace(
" " & Chr(
9)
& Chr(
10)) returns True
1452 Dim bWhitespace As Boolean
' Return value
1453 Const cstThisSub =
"String.IsWhitespace
"
1454 Const cstSubArgs =
"InputStr
"
1456 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1460 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1461 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1465 If Len(InputStr)
> 0 Then bWhitespace = SF_String.IsRegex(InputStr, REGEXWHITESPACES, CaseSensitive := False)
1468 IsWhitespace = bWhitespace
1469 SF_Utils._ExitFunction(cstThisSub)
1473 End Function
' ScriptForge.SF_String.IsWhitespace
1475 REM -----------------------------------------------------------------------------
1476 Public Function JustifyCenter(Optional ByRef InputStr As Variant _
1477 , Optional ByVal Length As Variant _
1478 , Optional ByVal Padding As Variant _
1480 ''' Return the input string center justified
1481 ''' Args:
1482 ''' InputStr: the input string
1483 ''' Length: the resulting string length (default = length of input string)
1484 ''' Padding: the padding (single) character (default = the ascii space)
1485 ''' Returns:
1486 ''' The input string without its leading and trailing white spaces
1487 ''' completed left and right up to a total length of Length with the character Padding
1488 ''' If the input string is empty, the returned string is empty too
1489 ''' If the requested length is shorter than the center justified input string,
1490 ''' then the returned string is truncated
1491 ''' Examples:
1492 ''' SF_String.JustifyCenter(
" ABCDE
", Padding :=
"x
") returns
"xxABCDEFxx
"
1494 Dim sJustify As String
' Return value
1495 Dim lLength As Long
' Length of input string
1496 Dim lJustLength As Long
' Length of trimmed input string
1497 Dim sPadding As String
' Series of Padding characters
1498 Const cstThisSub =
"String.JustifyCenter
"
1499 Const cstSubArgs =
"InputStr, [length=Len(InputStr)], [Padding=
"" ""]
"
1501 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1502 sJustify =
""
1505 If IsMissing(Length) Or IsEmpty(Length) Then Length =
0
1506 If IsMissing(Padding) Or IsMissing(Padding) Then Padding =
" "
1507 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1508 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1509 If Not SF_Utils._Validate(Length,
"Length
", V_NUMERIC) Then GoTo Finally
1510 If Not SF_Utils._Validate(Padding,
"Padding
", V_STRING) Then GoTo Finally
1512 If Len(Padding) =
0 Then Padding =
" " Else Padding = Left(Padding,
1)
1515 lLength = Len(InputStr)
1516 If Length =
0 Then Length = lLength
1517 If lLength
> 0 Then
1518 sJustify = SF_String.TrimExt(InputStr)
' Trim left and right
1519 lJustLength = Len(sJustify)
1520 If lJustLength
> Length Then
1521 sJustify = Mid(sJustify, Int((lJustLength - Length) /
2) +
1, Length)
1522 ElseIf lJustLength
< Length Then
1523 sPadding = String(Int((Length - lJustLength) /
2), Padding)
1524 sJustify = sPadding
& sJustify
& sPadding
1525 If Len(sJustify)
< Length Then sJustify = sJustify
& Padding
' One Padding char is lacking when lJustLength is odd
1530 JustifyCenter = sJustify
1531 SF_Utils._ExitFunction(cstThisSub)
1535 End Function
' ScriptForge.SF_String.JustifyCenter
1537 REM -----------------------------------------------------------------------------
1538 Public Function JustifyLeft(Optional ByRef InputStr As Variant _
1539 , Optional ByVal Length As Variant _
1540 , Optional ByVal Padding As Variant _
1542 ''' Return the input string left justified
1543 ''' Args:
1544 ''' InputStr: the input string
1545 ''' Length: the resulting string length (default = length of input string)
1546 ''' Padding: the padding (single) character (default = the ascii space)
1547 ''' Returns:
1548 ''' The input string without its leading white spaces
1549 ''' filled up to a total length of Length with the character Padding
1550 ''' If the input string is empty, the returned string is empty too
1551 ''' If the requested length is shorter than the left justified input string,
1552 ''' then the returned string is truncated
1553 ''' Examples:
1554 ''' SF_String.JustifyLeft(
" ABCDE
", Padding :=
"x
") returns
"ABCDE xxx
"
1556 Dim sJustify As String
' Return value
1557 Dim lLength As Long
' Length of input string
1558 Const cstThisSub =
"String.JustifyLeft
"
1559 Const cstSubArgs =
"InputStr, [length=Len(InputStr)], [Padding=
"" ""]
"
1561 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1562 sJustify =
""
1565 If IsMissing(Length) Or IsEmpty(Length) Then Length =
0
1566 If IsMissing(Padding) Or IsMissing(Padding) Then Padding =
" "
1567 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1568 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1569 If Not SF_Utils._Validate(Length,
"Length
", V_NUMERIC) Then GoTo Finally
1570 If Not SF_Utils._Validate(Padding,
"Padding
", V_STRING) Then GoTo Finally
1572 If Len(Padding) =
0 Then Padding =
" " Else Padding = Left(Padding,
1)
1575 lLength = Len(InputStr)
1576 If Length =
0 Then Length = lLength
1577 If lLength
> 0 Then
1578 sJustify = SF_String.ReplaceRegex(InputStr, REGEXLTRIM,
"")
' Trim left
1579 If Len(sJustify)
>= Length Then
1580 sJustify = Left(sJustify, Length)
1582 sJustify = sJustify
& String(Length - Len(sJustify), Padding)
1587 JustifyLeft = sJustify
1588 SF_Utils._ExitFunction(cstThisSub)
1592 End Function
' ScriptForge.SF_String.JustifyLeft
1594 REM -----------------------------------------------------------------------------
1595 Public Function JustifyRight(Optional ByRef InputStr As Variant _
1596 , Optional ByVal Length As Variant _
1597 , Optional ByVal Padding As Variant _
1599 ''' Return the input string right justified
1600 ''' Args:
1601 ''' InputStr: the input string
1602 ''' Length: the resulting string length (default = length of input string)
1603 ''' Padding: the padding (single) character (default = the ascii space)
1604 ''' Returns:
1605 ''' The input string without its trailing white spaces
1606 ''' preceded up to a total length of Length with the character Padding
1607 ''' If the input string is empty, the returned string is empty too
1608 ''' If the requested length is shorter than the right justified input string,
1609 ''' then the returned string is right-truncated
1610 ''' Examples:
1611 ''' SF_String.JustifyRight(
" ABCDE
", Padding :=
"x
") returns
"x ABCDE
"
1613 Dim sJustify As String
' Return value
1614 Dim lLength As Long
' Length of input string
1615 Const cstThisSub =
"String.JustifyRight
"
1616 Const cstSubArgs =
"InputStr, [length=Len(InputStr)], [Padding=
"" ""]
"
1618 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1619 sJustify =
""
1622 If IsMissing(Length) Or IsEmpty(Length) Then Length =
0
1623 If IsMissing(Padding) Or IsMissing(Padding) Then Padding =
" "
1624 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1625 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1626 If Not SF_Utils._Validate(Length,
"Length
", V_NUMERIC) Then GoTo Finally
1627 If Not SF_Utils._Validate(Padding,
"Padding
", V_STRING) Then GoTo Finally
1629 If Len(Padding) =
0 Then Padding =
" " Else Padding = Left(Padding,
1)
1632 lLength = Len(InputStr)
1633 If Length =
0 Then Length = lLength
1634 If lLength
> 0 Then
1635 sJustify = SF_String.ReplaceRegex(InputStr, REGEXRTRIM,
"")
' Trim right
1636 If Len(sJustify)
>= Length Then
1637 sJustify = Right(sJustify, Length)
1639 sJustify = String(Length - Len(sJustify), Padding)
& sJustify
1644 JustifyRight = sJustify
1645 SF_Utils._ExitFunction(cstThisSub)
1649 End Function
' ScriptForge.SF_String.JustifyRight
1651 REM -----------------------------------------------------------------------------
1652 Public Function Methods() As Variant
1653 ''' Return the list of public methods of the String service as an array
1656 "Capitalize
" _
1657 ,
"Count
" _
1658 ,
"EndWith
" _
1659 ,
"Escape
" _
1660 ,
"ExpandTabs
" _
1661 ,
"FilterNotPrintable
" _
1662 ,
"FindRegex
" _
1663 ,
"HashStr
" _
1664 ,
"HtmlEncode
" _
1665 ,
"IsADate
" _
1666 ,
"IsAlpha
" _
1667 ,
"IsAlphaNum
" _
1668 ,
"IsAscii
" _
1669 ,
"IsDigit
" _
1670 ,
"IsEmail
" _
1671 ,
"IsFileName
" _
1672 ,
"IsHexDigit
" _
1673 ,
"IsIPv4
" _
1674 ,
"IsLike
" _
1675 ,
"IsLower
" _
1676 ,
"IsPrintable
" _
1677 ,
"IsRegex
" _
1678 ,
"IsSheetName
" _
1679 ,
"IsTitle
" _
1680 ,
"IsUpper
" _
1681 ,
"IsUrl
" _
1682 ,
"IsWhitespace
" _
1683 ,
"JustifyCenter
" _
1684 ,
"JustifyLeft
" _
1685 ,
"JustifyRight
" _
1686 ,
"Quote
" _
1687 ,
"ReplaceChar
" _
1688 ,
"ReplaceRegex
" _
1689 ,
"ReplaceStr
" _
1690 ,
"Represent
" _
1691 ,
"Reverse
" _
1692 ,
"SplitLines
" _
1693 ,
"SplitNotQuoted
" _
1694 ,
"StartsWith
" _
1695 ,
"TrimExt
" _
1696 ,
"Unescape
" _
1697 ,
"Unquote
" _
1698 ,
"Wrap
" _
1701 End Function
' ScriptForge.SF_String.Methods
1703 REM -----------------------------------------------------------------------------
1704 Public Function Properties() As Variant
1705 ''' Return the list or properties as an array
1707 Properties = Array( _
1709 ,
"sfCRLF
" _
1710 ,
"sfLF
" _
1711 ,
"sfNEWLINE
" _
1712 ,
"sfTAB
" _
1715 End Function
' ScriptForge.SF_Session.Properties
1717 REM -----------------------------------------------------------------------------
1718 Public Function Quote(Optional ByRef InputStr As Variant _
1719 , Optional ByVal QuoteChar As String _
1721 ''' Return the input string surrounded with double quotes
1722 ''' Used f.i. to prepare a string field to be stored in a csv-like file
1723 ''' Args:
1724 ''' InputStr: the input string
1725 ''' QuoteChar: either
" (default) or
'
1726 ''' Returns:
1727 ''' Existing - including leading and/or trailing - double quotes are doubled
1728 ''' Examples:
1729 ''' SF_String.Quote(
"àé
""n ΣlPµ Русский
") returns
"""àé
""""n ΣlPµ Русский
"""
1731 Dim sQuote As String
' Return value
1732 Const cstDouble =
"""" : Const cstSingle =
"'"
1733 Const cstEscape =
"\
"
1734 Const cstThisSub =
"String.Quote
"
1735 Const cstSubArgs =
"InputStr
"
1737 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1738 sQuote =
""
1741 If IsMissing(QuoteChar) Or IsEmpty(QuoteChar) Then QuoteChar = cstDouble
1742 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1743 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1744 If Not SF_Utils._Validate(QuoteChar,
"QuoteChar
", V_STRING, Array(cstDouble, cstSingle)) Then GoTo Finally
1748 If QuoteChar = cstDouble Then
1749 sQuote = cstDouble
& Replace(InputStr, cstDouble, cstDouble
& cstDouble)
& cstDouble
1751 sQuote = Replace(InputStr, cstEscape, cstEscape
& cstEscape)
1752 sQuote = cstSingle
& Replace(sQuote, cstSingle, cstEscape
& cstSingle)
& cstSingle
1757 SF_Utils._ExitFunction(cstThisSub)
1761 End Function
' ScriptForge.SF_String.Quote
1763 REM -----------------------------------------------------------------------------
1764 Public Function ReplaceChar(Optional ByRef InputStr As Variant _
1765 , Optional ByVal Before As Variant _
1766 , Optional ByVal After As Variant _
1768 ''' Replace in InputStr all occurrences of any character from Before
1769 ''' by the corresponding character in After
1770 ''' Args:
1771 ''' InputStr: the input string on which replacements should occur
1772 ''' Before: a string of characters to replace
1 by
1 in InputStr
1773 ''' After: the replacing characters
1774 ''' Returns:
1775 ''' The new string after replacement of Nth character of Before by the Nth character of After
1776 ''' Replacements are done one by one =
> potential overlaps
1777 ''' If the length of Before is larger than the length of After,
1778 ''' the residual characters of Before are replaced by the last character of After
1779 ''' The input string when Before is the zero-length string
1780 ''' Examples: easily remove accents
1781 ''' SF_String.ReplaceChar(
"Protégez votre vie privée
",
"àâãçèéêëîïôöûüýÿ
",
"aaaceeeeiioouuyy
")
1782 ''' returns
"Protegez votre vie privee
"
1783 ''' SF_String.ReplaceChar(
"Protégez votre vie privée
", SF_String.CHARSWITHACCENT, SF_String.CHARSWITHOUTACCENT)
1785 Dim sOutput As String
' Return value
1786 Dim iCaseSensitive As Integer
' Always
0 (True)
1787 Dim sBefore As String
' A single character extracted from InputStr
1788 Dim sAfter As String
' A single character extracted from After
1789 Dim lInStr As Long
' Output of InStr()
1791 Const cstThisSub =
"String.ReplaceChar
"
1792 Const cstSubArgs =
"InputStr, Before, After
"
1794 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1795 sOutput =
""
1798 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1799 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1800 If Not SF_Utils._Validate(Before,
"Before
", V_STRING) Then GoTo Finally
1801 If Not SF_Utils._Validate(After,
"After
", V_STRING) Then GoTo Finally
1805 ' Replace standard function =
> Replace(string, before, after, start, occurrences, casesensitive)
1809 ' Replace one by one up length of Before and After
1810 If Len(Before)
> 0 Then
1812 Do While i
<= Len(sOutput)
1813 sBefore = Mid(sOutput, i,
1)
1814 lInStr = InStr(
1, Before, sBefore, iCaseSensitive)
1815 If lInStr
> 0 Then
1816 If Len(After) =
0 Then
1817 sAfter =
""
1818 ElseIf lInStr
> Len(After) Then
1819 sAfter = Right(After,
1)
1821 sAfter = Mid(After, lInStr,
1)
1823 sOutput = Left(sOutput, i -
1)
& Replace(sOutput, sBefore, sAfter, i, Empty, iCaseSensitive)
1830 ReplaceChar = sOutput
1831 SF_Utils._ExitFunction(cstThisSub)
1835 End Function
' ScriptForge.SF_String.ReplaceChar
1837 REM -----------------------------------------------------------------------------
1838 Public Function ReplaceRegex(Optional ByRef InputStr As Variant _
1839 , Optional ByVal Regex As Variant _
1840 , Optional ByRef NewStr As Variant _
1841 , Optional ByVal CaseSensitive As Variant _
1843 ''' Replace in InputStr all occurrences of a given regular expression by NewStr
1844 ''' Args:
1845 ''' InputStr: the input string where replacements should occur
1846 ''' Regex: the regular expression
1847 ''' NewStr: the replacing string
1848 ''' CaseSensitive: default = False
1849 ''' Returns:
1850 ''' The new string after all replacements
1851 ''' Examples:
1852 ''' SF_String.ReplaceRegex(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"[a-z]
",
"x
", CaseSensitive := True)
1853 ''' returns
"Lxxxx xxxxx xxxxx xxx xxxx, xxxxxxxxxxx xxxxxxxxxx xxxx.
"
1854 ''' SF_String.ReplaceRegex(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
",
"\b[a-z]+\b
",
"x
", CaseSensitive := False)
1855 ''' returns
"x x x x x, x x x.
" (each word is replaced by x)
1858 Dim sOutput As String
' Return value
1859 Dim lStartOld As Long
' Previous start of search
1860 Dim lStartNew As Long
' Next start of search
1861 Dim sSubstring As String
' Substring to replace
1862 Const cstThisSub =
"String.ReplaceRegex
"
1863 Const cstSubArgs =
"InputStr, Regex, NewStr, [CaseSensitive=False]
"
1865 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1866 sOutput =
""
1869 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1870 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1871 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1872 If Not SF_Utils._Validate(Regex,
"Regex
", V_STRING) Then GoTo Finally
1873 If Not SF_Utils._Validate(NewStr,
"NewStr
", V_STRING) Then GoTo Finally
1874 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1878 sOutput =
""
1882 Do While lStartNew
>=
1 And lStartNew
<= Len(InputStr)
1883 sSubstring = SF_String.FindRegex(InputStr, Regex, lStartNew, CaseSensitive)
1884 If lStartNew =
0 Then
' Regex not found
1885 ' Copy remaining substring of InputStr before leaving
1886 sOutput = sOutput
& Mid(InputStr, lStartOld)
1889 ' Append the interval between
2 occurrences and the replacing string
1890 If lStartNew
> lStartOld Then sOutput = sOutput
& Mid(InputStr, lStartOld, lStartNew - lStartOld)
1891 sOutput = sOutput
& NewStr
1892 lStartOld = lStartNew + Len(sSubstring)
1893 lStartNew = lStartOld
1897 ReplaceRegex = sOutput
1898 SF_Utils._ExitFunction(cstThisSub)
1902 End Function
' ScriptForge.SF_String.ReplaceRegex
1904 REM -----------------------------------------------------------------------------
1905 Public Function ReplaceStr(Optional ByRef InputStr As Variant _
1906 , Optional ByVal OldStr As Variant _
1907 , Optional ByVal NewStr As Variant _
1908 , Optional ByVal Occurrences As Variant _
1909 , Optional ByVal CaseSensitive As Variant _
1911 ''' Replace in InputStr some or all occurrences of OldStr by NewStr
1912 ''' Args:
1913 ''' InputStr: the input string on which replacements should occur
1914 ''' OldStr: the string to replace or a
1D array of strings to replace
1915 ''' Zero-length strings are ignored
1916 ''' NewStr: the replacing string or a
1D array of replacing strings
1917 ''' If OldStr is an array
1918 ''' each occurrence of any of the items of OldStr is replaced by NewStr
1919 ''' If OldStr and NewStr are arrays
1920 ''' replacements occur one by one up to the UBound of NewStr
1921 ''' remaining OldStr(ings) are replaced by the last element of NewStr
1922 ''' Occurrences: the maximum number of replacements (
0, default, = all occurrences)
1923 ''' Is applied for each single replacement when OldStr is an array
1924 ''' CaseSensitive: True or False (default)
1925 ''' Returns:
1926 ''' The new string after replacements
1927 ''' Replacements are done one by one when OldStr is an array =
> potential overlaps
1928 ''' Examples:
1929 ''' SF_String.ReplaceStr(
"abCcdefghHij
", Array(
"c
",
"h
"), Array(
"Y
",
"Z
"), CaseSensitive := False) returns
"abYYdefgZZij
"
1931 Dim sOutput As String
' Return value
1932 Dim iCaseSensitive As Integer
' Integer alias for boolean CaseSensitive
1933 Dim vOccurrences As Variant
' Variant alias for Integer Occurrences
1934 Dim sNewStr As String
' Alias for a NewStr item
1935 Dim i As Long, j As Long
1936 Const cstThisSub =
"String.ReplaceStr
"
1937 Const cstSubArgs =
"InputStr, OldStr, NewStr, [Occurrences=
0], [CaseSensitive=False]
"
1939 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
1940 sOutput =
""
1943 If IsMissing(Occurrences) Or IsEmpty(Occurrences) Then Occurrences =
0
1944 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
1945 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
1946 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
1947 If IsArray(OldStr) Then
1948 If Not SF_Utils._ValidateArray(OldStr,
"OldStr
",
1, V_STRING, True) Then GoTo Finally
1950 If Not SF_Utils._Validate(OldStr,
"OldStr
", V_STRING) Then GoTo Finally
1952 If IsArray(NewStr) Then
1953 If Not SF_Utils._ValidateArray(NewStr,
"NewStr
",
1, V_STRING, True) Then GoTo Finally
1955 If Not SF_Utils._Validate(NewStr,
"NewStr
", V_STRING) Then GoTo Finally
1957 If Not SF_Utils._Validate(Occurrences,
"Occurrences
", V_NUMERIC) Then GoTo Finally
1958 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
1962 ' Replace standard function =
> Replace(string, before, after, start, occurrences, casesensitive)
1964 iCaseSensitive = Iif(CaseSensitive,
0,
1)
' 1 = False ;)
1965 vOccurrences = Iif(Occurrences =
0, Empty, Occurrences)
' Empty = no limit
1966 If Not IsArray(OldStr) Then OldStr = Array(OldStr)
1967 If Not IsArray(NewStr) Then NewStr = Array(NewStr)
1969 ' Replace one by one up to UBounds of Old and NewStr
1970 j = LBound(NewStr) -
1
1971 For i = LBound(OldStr) To UBound(OldStr)
1973 If j
<= UBound(NewStr) Then sNewStr = NewStr(j)
' Else do not change
1974 If StrComp(OldStr(i), sNewStr,
1)
<> 0 Then
1975 sOutput = Replace(sOutput, OldStr(i), sNewStr,
1, vOccurrences, iCaseSensitive)
1980 ReplaceStr = sOutput
1981 SF_Utils._ExitFunction(cstThisSub)
1985 End Function
' ScriptForge.SF_String.ReplaceStr
1987 REM -----------------------------------------------------------------------------
1988 Public Function Represent(Optional ByRef AnyValue As Variant _
1989 , Optional ByVal MaxLength As Variant _
1991 ''' Return a readable (string) form of the argument, truncated at MaxLength
1992 ''' Args:
1993 ''' AnyValue: really any value (object, date, whatever)
1994 ''' MaxLength: the maximum length of the resulting string (Default =
0, unlimited)
1995 ''' Returns:
1996 ''' The argument converted or transformed into a string of a maximum length = MaxLength
1997 ''' Objects are surrounded with square brackets ([])
1998 ''' In strings, tabs and line breaks are replaced by \t, \n or \r
1999 ''' If the effective length exceeds MaxLength, the final part of the string is replaced by
" ... (N)
"
2000 ''' where N = the total length of the string before truncation
2001 ''' Examples:
2002 ''' SF_String.Represent(
"this is a usual string
") returns
"this is a usual string
"
2003 ''' SF_String.Represent(
"this is a usual string
",
15) returns
"this i ... (
22)
"
2004 ''' SF_String.Represent(
"this is a
" & Chr(
10)
& " 2-lines string
") returns
"this is a\n
2-lines string
"
2005 ''' SF_String.Represent(Empty) returns
"[EMPTY]
"
2006 ''' SF_String.Represent(Null) returns
"[NULL]
"
2007 ''' SF_String.Represent(Pi) returns
"3.142"
2008 ''' SF_String.Represent(CreateUnoService(
"com.sun.star.util.PathSettings
")) returns
"[com.sun.star.comp.framework.PathSettings]
"
2009 ''' SF_String.Represent(Array(
1,
2,
"Text
" & Chr(
9)
& "here
")) returns
"[ARRAY] (
0:
2) (
1,
2, Text\there)
"
2010 ''' Dim myDict As Variant : myDict = CreateScriptService(
"Dictionary
")
2011 ''' myDict.Add(
"A
",
1) : myDict.Add(
"B
",
2)
2012 ''' SF_String.Represent(myDict) returns
"[Dictionary] (
"A
":
1,
"B
":
2)
"
2014 Dim sRepr As String
' Return value
2015 Const cstThisSub =
"String.Represent
"
2016 Const cstSubArgs =
"AnyValue, [MaxLength=
0]
"
2018 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2019 sRepr =
""
2022 If IsMissing(AnyValue) Then AnyValue = Empty
2023 If IsMissing(MaxLength) Or IsEmpty(MaxLength) Then MaxLength =
0
2024 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2025 If Not SF_Utils._Validate(MaxLength,
"MaxLength
", V_NUMERIC) Then GoTo Finally
2029 sRepr = SF_Utils._Repr(AnyValue, MaxLength)
2030 If MaxLength
> 0 And MaxLength
< Len(sRepr) Then sRepr = sRepr
& " ... (
" & Len(sRepr)
& ")
"
2034 SF_Utils._ExitFunction(cstThisSub)
2038 End Function
' ScriptForge.SF_String.Represent
2040 REM -----------------------------------------------------------------------------
2041 Public Function Reverse(Optional ByRef InputStr As Variant) As String
2042 ''' Return the input string in reversed order
2043 ''' It is equivalent to the standard StrReverse Basic function
2044 ''' The latter requires the OpTion VBASupport
1 statement to be present in the module
2045 ''' Args:
2046 ''' InputStr: the input string
2047 ''' Returns:
2048 ''' The input string in reversed order
2049 ''' Examples:
2050 ''' SF_String.Reverse(
"abcdefghij
") returns
"jihgfedcba
"
2052 Dim sReversed As String
' Return value
2053 Dim lLength As Long
' Length of input string
2055 Const cstThisSub =
"String.Reverse
"
2056 Const cstSubArgs =
"InputSt
"
2058 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2059 sReversed =
""
2062 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2063 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2067 lLength = Len(InputStr)
2068 If lLength
> 0 Then
2069 sReversed = Space(lLength)
2070 For i =
1 To lLength
2071 Mid(sReversed, i,
1) = Mid(InputStr, lLength - i +
1)
2077 SF_Utils._ExitFunction(cstThisSub)
2081 End Function
' ScriptForge.SF_String.Reverse
2083 REM -----------------------------------------------------------------------------
2084 Public Function SetProperty(Optional ByVal PropertyName As Variant _
2085 , Optional ByRef Value As Variant _
2087 ''' Set a new value to the given property
2088 ''' Args:
2089 ''' PropertyName: the name of the property as a string
2090 ''' Value: its new value
2091 ''' Exceptions
2092 ''' ARGUMENTERROR The property does not exist
2094 Const cstThisSub =
"String.SetProperty
"
2095 Const cstSubArgs =
"PropertyName, Value
"
2097 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2101 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2102 If Not SF_Utils._Validate(PropertyName,
"PropertyName
", V_STRING, Properties()) Then GoTo Catch
2106 Select Case UCase(PropertyName)
2111 SF_Utils._ExitFunction(cstThisSub)
2115 End Function
' ScriptForge.SF_String.SetProperty
2117 REM -----------------------------------------------------------------------------
2118 Public Function SplitLines(Optional ByRef InputStr As Variant _
2119 , Optional ByVal KeepBreaks As Variant _
2121 ''' Return an array of the lines in a string, breaking at line boundaries
2122 ''' Line boundaries include LF(
10), VT(
12), CR(
13), LF+CR, File separator(
28), Group separator(
29), Record separator(
30),
2123 ''' Next Line(
133), Line separator(
8232), Paragraph separator(
8233)
2124 ''' Args:
2125 ''' InputStr: the input string
2126 ''' KeepBreaks: when True, line breaks are preserved in the output array (default = False)
2127 ''' Returns:
2128 ''' An array of all the individual lines
2129 ''' Examples:
2130 ''' SF_String.SplitLines(
"Line1
" & Chr(
10)
& "Line2
" & Chr(
13)
& "Line3
") returns (
"Line1
",
"Line2
",
"Line3
")
2131 ''' SF_String.SplitLines(
"Line1
" & Chr(
10)
& "Line2
" & Chr(
13)
& "Line3
" & Chr(
10)) returns (
"Line1
",
"Line2
",
"Line3
",
"")
2133 Dim vSplit As Variant
' Return value
2134 Dim vLineBreaks As Variant
' Array of recognized line breaks
2135 Dim vTokenizedBreaks As Variant
' Array of line breaks extended with tokens
2136 Dim sAlias As String
' Alias for input string
2137 ' The procedure uses (dirty) placeholders to identify line breaks
2138 ' The used tokens are presumed unlikely present in text strings
2139 Dim sTokenCRLF As String
' Token to identify combined CR + LF
2140 Dim sToken As String
' Token to identify any line break
2142 Const cstThisSub =
"String.SplitLines
"
2143 Const cstSubArgs =
"InputStr, [KeepBreaks=False]
"
2145 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2149 If IsMissing(KeepBreaks) Or IsEmpty(KeepBreaks) Then KeepBreaks = False
2150 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2151 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2152 If Not SF_Utils._Validate(KeepBreaks,
"KeepBreaks
", V_BOOLEAN) Then GoTo Finally
2156 ' In next list CR + LF must precede CR and LF
2157 vLineBreaks = Array(SF_String.sfCRLF, SF_String.sfLF, Chr(
12), SF_String.sfCR _
2158 , Chr(
28), Chr(
29), Chr(
30), Chr(
133), Chr(
8232), Chr(
8233))
2160 If KeepBreaks = False Then
2161 ' Replace line breaks by linefeeds and split on linefeeds
2162 vSplit = Split(SF_String.ReplaceStr(InputStr, vLineBreaks, SF_String.sfLF, CaseSensitive := False), SF_String.sfLF)
2164 sTokenCRLF = Chr(
1)
& "$
" & Chr(
2)
& "*
" & Chr(
3)
& "$
" & Chr(
1)
2165 sToken = Chr(
1)
& "$
" & Chr(
2)
& "*
" & Chr(
3)
& "$
" & Chr(
2)
2166 vTokenizedBreaks = Array() : ReDim vTokenizedBreaks(
0 To UBound(vLineBreaks))
2167 ' Extend breaks with token
2168 For i =
0 To UBound(vLineBreaks)
2169 vTokenizedBreaks(i) = Iif(i =
0, sTokenCRLF, vLineBreaks(i))
& sToken
2171 sAlias = SF_String.ReplaceStr(InputStr, vLineBreaks, vTokenizedBreaks, CaseSensitive := False)
2172 ' Suppress CRLF tokens and split
2173 vSplit = Split(Replace(sAlias, sTokenCRLF, SF_String.sfCRLF), sToken)
2178 SF_Utils._ExitFunction(cstThisSub)
2182 End Function
' ScriptForge.SF_String.SplitLines
2184 REM -----------------------------------------------------------------------------
2185 Public Function SplitNotQuoted(Optional ByRef InputStr As Variant _
2186 , Optional ByVal Delimiter As Variant _
2187 , Optional ByVal Occurrences As Variant _
2188 , Optional ByVal QuoteChar As Variant _
2190 ''' Split a string on Delimiter into an array. If Delimiter is part of a quoted (sub)string, it is ignored
2191 ''' (used f.i. for parsing of csv-like records)
2192 ''' Args:
2193 ''' InputStr: the input string
2194 ''' Might contain quoted substrings:
2195 ''' The quoting character must be the double quote (
")
2196 ''' To preserve a quoting character inside the quoted substring, use (\) or (
") as escape character
2197 ''' =
> [str\
"i
""ng] means [str
"i
"ng]
2198 ''' Delimiter: A string of one or more characters that is used to delimit the input string
2199 ''' The default is the space character
2200 ''' Occurrences: The number of substrings to return (Default =
0, meaning no limit)
2201 ''' QuoteChar: The quoting character, either
" (default) or
'
2202 ''' Returns:
2203 ''' An array whose items are chunks of the input string, Delimiter not included
2204 ''' Examples:
2205 ''' SF_String.SplitNotQuoted(
"abc def ghi
") returns (
"abc
",
"def
",
"ghi
")
2206 ''' SF_String.SplitNotQuoted(
"abc,
""def,ghi
""",
",
") returns (
"abc
",
"""def,ghi
""")
2207 ''' SF_String.SplitNotQuoted(
"abc,
""def\
"",ghi
""",
",
") returns (
"abc
",
"""def\
"",ghi
""")
2208 ''' SF_String.SplitNotQuoted(
"abc,
""def\
"",ghi
"""",
",
",
") returns (
"abc
",
"""def\
"",ghi
""",
"")
2210 Dim vSplit As Variant
' Return value
2211 Dim lDelimLen As Long
' Length of Delimiter
2212 Dim vStart As Variant
' Array of start positions of quoted strings
2213 Dim vEnd As Variant
' Array of end positions of quoted strings
2214 Dim lInStr As Long
' InStr() on input string
2215 Dim lInStrPrev As Long
' Previous value of lInputStr
2216 Dim lBound As Long
' UBound of vStart and vEnd
2217 Dim lMin As Long
' Lower bound to consider when searching vStart and vEnd
2218 Dim oCharacterClass As Object
' com.sun.star.i18n.CharacterClassification
2219 Dim oLocale As Object
' com.sun.star.lang.Locale
2220 Dim oParse As Object
' com.sun.star.i18n.ParseResult
2221 Dim sChunk As String
' Substring of InputStr
2222 Dim bSplit As Boolean
' New chunk found or not
2224 Const cstDouble =
"""" : Const cstSingle =
"'"
2225 Const cstThisSub =
"String.SplitNotQuoted
"
2226 Const cstSubArgs =
"InputStr, [Delimiter=
"" ""], [Occurrences=
0], [QuoteChar=
""" & cstDouble
& """"
2228 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2232 If IsMissing(Delimiter) Or IsEmpty(Delimiter) Then Delimiter =
" "
2233 If IsMissing(Occurrences) Or IsEmpty(Occurrences) Then Occurrences =
0
2234 If IsMissing(QuoteChar) Or IsEmpty(QuoteChar) Then QuoteChar = cstDouble
2235 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2236 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2237 If Not SF_Utils._Validate(Delimiter,
"Delimiter
", V_STRING) Then GoTo Finally
2238 If Not SF_Utils._Validate(Occurrences,
"Occurrences
", V_NUMERIC) Then GoTo Finally
2239 If Not SF_Utils._Validate(QuoteChar,
"QuoteChar
", V_STRING, Array(cstDouble, cstSingle)) Then GoTo Finally
2241 If Len(Delimiter) =
0 Then Delimiter =
" "
2244 If Occurrences =
1 Or InStr(
1, InputStr, Delimiter,
0) =
0 Then
' No reason to split
2245 vSplit = Array(InputStr)
2246 ElseIf InStr(
1, InputStr, QuoteChar,
0) =
0 Then
' No reason to make a complex split
2247 If Occurrences
> 0 Then vSplit = Split(InputStr, Delimiter, Occurrences) Else vSplit = Split(InputStr, Delimiter)
2249 If Occurrences
< 0 Then Occurrences =
0
2250 Set oCharacterClass = SF_Utils._GetUNOService(
"CharacterClass
")
2251 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
2253 ' Build an array of start/end positions of quoted strings containing at least
1x the Delimiter
2254 vStart = Array() : vEnd = Array()
2255 lInStr = InStr(
1, InputStr, QuoteChar)
2256 Do While lInStr
> 0
2257 lBound = UBound(vStart)
2258 ' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1i18n_1_1XCharacterClassification.html#ad5f1be91fbe86853200391f828d4166b
2259 Set oParse = oCharacterClass.parsePredefinedToken( _
2260 Iif(QuoteChar = cstDouble, com.sun.star.i18n.KParseType.DOUBLE_QUOTE_STRING, com.sun.star.i18n.KParseType.SINGLE_QUOTE_NAME) _
2261 , InputStr, lInStr -
1, oLocale,
0,
"",
0,
"")
2262 If oParse.CharLen
> 0 Then
' Is parsing successful ?
2263 ' Is there some delimiter ?
2264 If InStr(
1, oParse.DequotedNameOrString, Delimiter,
0)
> 0 Then
2265 vStart = SF_Array.Append(vStart, lInStr +
0)
2266 vEnd = SF_Array.Append(vEnd, lInStr + oParse.CharLen -
1)
2268 lInStr = InStr(lInStr + oParse.CharLen, InputStr, QuoteChar)
2274 lBound = UBound(vStart)
2275 lDelimLen = Len(Delimiter)
2276 If lBound
< 0 Then
' Usual split is applicable
2277 vSplit = Split(InputStr, Delimiter, Occurrences)
2279 ' Split chunk by chunk
2282 lInStr = InStr(
1, InputStr, Delimiter,
0)
2283 Do While lInStr
> 0
2284 If Occurrences
> 0 And Occurrences = UBound(vSplit) -
1 Then Exit Do
2286 ' Ignore found Delimiter if in quoted string
2287 For i = lMin To lBound
2288 If lInStr
< vStart(i) Then
2291 ElseIf lInStr
> vStart(i) And lInStr
< vEnd (i) Then
2295 If i = lBound Then bSplit = True Else bSplit = ( lInStr
< vStart(lMin) )
2298 ' Build next chunk and store in split array
2300 If lInStrPrev =
0 Then
' First chunk
2301 sChunk = Left(InputStr, lInStr -
1)
2303 sChunk = Mid(InputStr, lInStrPrev + lDelimLen, lInStr - lInStrPrev - lDelimLen)
2305 vSplit = SF_Array.Append(vSplit, sChunk
& "")
2308 lInStr = InStr(lInStr + lDelimLen, InputStr, Delimiter,
0)
2310 If Occurrences =
0 Or Occurrences
> UBound(vSplit) +
1 Then
2311 sChunk = Mid(InputStr, lInStrPrev + lDelimLen)
' Append last chunk
2312 vSplit = SF_Array.Append(vSplit, sChunk
& "")
2318 SplitNotQuoted = vSplit
2319 SF_Utils._ExitFunction(cstThisSub)
2323 End Function
' ScriptForge.SF_String.SplitNotQuoted
2325 REM -----------------------------------------------------------------------------
2326 Public Function StartsWith(Optional ByRef InputStr As Variant _
2327 , Optional ByVal Substring As Variant _
2328 , Optional ByVal CaseSensitive As Variant _
2330 ''' Returns True if the first characters of InputStr are identical to Substring
2331 ''' Args:
2332 ''' InputStr: the input string
2333 ''' Substring: the prefixing characters
2334 ''' CaseSensitive: default = False
2335 ''' Returns:
2336 ''' True if the comparison is satisfactory
2337 ''' False if either InputStr or Substring have a length =
0
2338 ''' False if Substr is longer than InputStr
2339 ''' Examples:
2340 ''' SF_String.StartsWith(
"abcdefg
",
"ABC
") returns True
2341 ''' SF_String.StartsWith(
"abcdefg
",
"ABC
", CaseSensitive := True) returns False
2343 Dim bStartsWith As Boolean
' Return value
2344 Dim lSub As Long
' Length of SUbstring
2345 Const cstThisSub =
"String.StartsWith
"
2346 Const cstSubArgs =
"InputStr, Substring, [CaseSensitive=False]
"
2348 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2352 If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
2353 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2354 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2355 If Not SF_Utils._Validate(Substring,
"Substring
", V_STRING) Then GoTo Finally
2356 If Not SF_Utils._Validate(CaseSensitive,
"CaseSensitive
", V_BOOLEAN) Then GoTo Finally
2360 lSub = Len(Substring)
2361 If Len(InputStr)
> 0 And lSub
> 0 And lSub
<= Len(InputStr) Then
2362 bStartsWith = ( StrComp(Left(InputStr, lSub), Substring, Iif(CaseSensitive,
1,
0)) =
0 )
2366 StartsWith = bStartsWith
2367 SF_Utils._ExitFunction(cstThisSub)
2371 End Function
' ScriptForge.SF_String.StartsWith
2373 REM -----------------------------------------------------------------------------
2374 Public Function TrimExt(Optional ByRef InputStr As Variant) As String
2375 ''' Return the input string without its leading and trailing whitespaces
2376 ''' Args:
2377 ''' InputStr: the input string
2378 ''' Returns:
2379 ''' The input string without its leading and trailing white spaces
2380 ''' Examples:
2381 ''' SF_String.TrimExt(
" ABCDE
" & Chr(
9)
& Chr(
10)
& Chr(
13)
& " ") returns
"ABCDE
"
2383 Dim sTrim As String
' Return value
2384 Const cstThisSub =
"String.TrimExt
"
2385 Const cstSubArgs =
"InputStr
"
2387 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2388 sTrim =
""
2391 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2392 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2396 If Len(InputStr)
> 0 Then
2397 sTrim = SF_String.ReplaceRegex(InputStr, REGEXLTRIM,
"")
' Trim left
2398 sTrim = SF_String.ReplaceRegex(sTrim, REGEXRTRIM,
"")
' Trim right
2403 SF_Utils._ExitFunction(cstThisSub)
2407 End Function
' ScriptForge.SF_String.TrimExt
2409 REM -----------------------------------------------------------------------------
2410 Public Function Unescape(Optional ByRef InputStr As Variant) As String
2411 ''' Convert any escaped characters in the input string
2412 ''' Args:
2413 ''' InputStr: the input string
2414 ''' Returns:
2415 ''' The input string after replacement of \\, \n, \r, \t sequences
2416 ''' Examples:
2417 ''' SF_String.Unescape(
"abc\n\tdef\\n
") returns
"abc
" & Chr(
10)
& Chr(
9)
& "def\n
"
2419 Dim sUnescape As String
' Return value
2420 Dim sToken As String
' Placeholder unlikely to be present in input string
2421 Const cstThisSub =
"String.Unescape
"
2422 Const cstSubArgs =
"InputStr
"
2424 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2425 sUnescape =
""
2428 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2429 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2433 sToken = Chr(
1)
& "$
" & Chr(
2)
& "*
" & Chr(
3)
& "$
" & Chr(
1)
' Placeholder for
"\\
"
2434 sUnescape = SF_String.ReplaceStr( InputStr _
2435 , Array(
"\\
",
"\n
",
"\r
",
"\t
", sToken) _
2436 , Array(sToken, SF_String.sfLF, SF_String.sfCR, SF_String.sfTAB,
"\
") _
2440 Unescape = sUnescape
2441 SF_Utils._ExitFunction(cstThisSub)
2445 End Function
' ScriptForge.SF_String.Unescape
2447 REM -----------------------------------------------------------------------------
2448 Public Function Unquote(Optional ByRef InputStr As Variant _
2449 , Optional ByVal QuoteChar As String _
2451 ''' Reset a quoted string to its original content
2452 ''' (used f.i. for parsing of csv-like records)
2453 ''' Args:
2454 ''' InputStr: the input string
2455 ''' QuoteChar: either
" (default) or
'
2456 ''' Returns:
2457 ''' The input string after removal of leading/trailing quotes and escaped single/double quotes
2458 ''' The input string if not a quoted string
2459 ''' Examples:
2460 ''' SF_String.Unquote(
"""àé
""""n ΣlPµ Русский
""") returns
"àé
""n ΣlPµ Русский
"
2462 Dim sUnquote As String
' Return value
2463 Dim oCharacterClass As Object
' com.sun.star.i18n.CharacterClassification
2464 Dim oLocale As Object
' com.sun.star.lang.Locale
2465 Dim oParse As Object
' com.sun.star.i18n.ParseResult
2466 Const cstDouble =
"""" : Const cstSingle =
"'"
2467 Const cstThisSub =
"String.Unquote
"
2468 Const cstSubArgs =
"InputStr
"
2470 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2471 sUnquote =
""
2474 If IsMissing(QuoteChar) Or IsEmpty(QuoteChar) Then QuoteChar = cstDouble
2475 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2476 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2477 If Not SF_Utils._Validate(QuoteChar,
"QuoteChar
", V_STRING, Array(cstDouble, cstSingle)) Then GoTo Finally
2481 If Left(InputStr,
1)
<> """" Then
' No need to parse further
2484 Set oCharacterClass = SF_Utils._GetUNOService(
"CharacterClass
")
2485 Set oLocale = SF_Utils._GetUNOService(
"Locale
")
2487 ' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1i18n_1_1XCharacterClassification.html#ad5f1be91fbe86853200391f828d4166b
2488 Set oParse = oCharacterClass.parsePredefinedToken( _
2489 Iif(QuoteChar = cstDouble, com.sun.star.i18n.KParseType.DOUBLE_QUOTE_STRING, com.sun.star.i18n.KParseType.SINGLE_QUOTE_NAME) _
2490 , InputStr,
0, oLocale,
0,
"",
0,
"")
2491 If oParse.CharLen
> 0 Then
' Is parsing successful ?
2492 sUnquote = oParse.DequotedNameOrString
2500 SF_Utils._ExitFunction(cstThisSub)
2504 End Function
' ScriptForge.SF_String.Unquote
2506 REM -----------------------------------------------------------------------------
2507 Public Function Wrap(Optional ByRef InputStr As Variant _
2508 , Optional ByVal Width As Variant _
2509 , Optional ByVal TabSize As Variant _
2511 ''' Wraps every single paragraph in text (a string) so every line is at most Width characters long
2512 ''' Args:
2513 ''' InputStr: the input string
2514 ''' Width: the maximum number of characters in each line, default =
70
2515 ''' TabSize: before wrapping the text, the existing TAB (Chr(
9)) characters are replaced with spaces.
2516 ''' TabSize defines the TAB positions at TabSize +
1,
2 * TabSize +
1 , ... N * TabSize +
1
2517 ''' Default =
8
2518 ''' Returns:
2519 ''' Returns a zero-based array of output lines, without final newlines except the pre-existing line-breaks
2520 ''' Tabs are expanded. Symbolic line breaks are replaced by their hard equivalents
2521 ''' If the wrapped output has no content, the returned array is empty.
2522 ''' Examples:
2523 ''' SF_String.Wrap(
"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...
",
20)
2525 Dim vWrap As Variant
' Return value
2526 Dim vWrapLines
' Input string split on line breaks
2527 Dim sWrap As String
' Intermediate string
2528 Dim sLine As String
' Line after splitting on line breaks
2529 Dim lPos As Long
' Position in sLine already wrapped
2530 Dim lStart As Long
' Start position before and after regex search
2531 Dim sSpace As String
' Next whitespace
2532 Dim sChunk As String
' Next wrappable text chunk
2533 Const cstThisSub =
"String.Wrap
"
2534 Const cstSubArgs =
"InputStr, [Width=
70], [TabSize=
8]
"
2536 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
2540 If IsMissing(Width) Or IsEmpty(Width) Then Width =
70
2541 If IsMissing(TabSize) Or IsEmpty(TabSize) Then TabSize =
8
2542 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
2543 If Not SF_Utils._Validate(InputStr,
"InputStr
", V_STRING) Then GoTo Finally
2544 If Not SF_Utils._Validate(Width,
"Width
", V_NUMERIC) Then GoTo Finally
2545 If Not SF_Utils._Validate(TabSize,
"TabSize
", V_NUMERIC) Then GoTo Finally
2549 If Len(InputStr)
> 0 Then
2550 sWrap = SF_String.Unescape(InputStr)
' Replace symbolic breaks
2551 sWrap = SF_String.ExpandTabs(sWrap, TabSize)
' Interpret TABs to have a meaningful Width
2552 ' First, split full string
2553 vWrapLines = SF_String.SplitLines(sWrap, KeepBreaks := True)
' Keep pre-existing breaks
2554 If UBound(vWrapLines) =
0 And Len(sWrap)
<= Width Then
' Output a single line
2555 vWrap = Array(sWrap)
2557 ' Second, split each line on Width
2558 For Each sLine In vWrapLines
2559 If Len(sLine)
<= Width Then
2560 If UBound(vWrap)
< 0 Then vWrap = Array(sLine) Else vWrap = SF_Array.Append(vWrap, sLine)
2562 ' Scan sLine and accumulate found substrings up to Width
2565 sWrap =
""
2566 Do While lStart
<= Len(sLine)
2567 sSpace = SF_String.FindRegex(sLine, REGEXSPACES, lStart)
2568 If lStart =
0 Then lStart = Len(sLine) +
1
2569 sChunk = Mid(sLine, lPos +
1, lStart -
1 - lPos + Len(sSpace))
2570 If Len(sWrap) + Len(sChunk)
< Width Then
' Add chunk to current piece of line
2571 sWrap = sWrap
& sChunk
2572 Else
' Save current line and initialize next one
2573 If UBound(vWrap)
< 0 Then vWrap = Array(sWrap) Else vWrap = SF_Array.Append(vWrap, sWrap)
2576 lPos = lPos + Len(sChunk)
2579 ' Add last chunk
2580 If Len(sWrap)
> 0 Then
2581 If UBound(vWrap)
< 0 Then vWrap = Array(sWrap) Else vWrap = SF_Array.Append(vWrap, sWrap)
2590 SF_Utils._ExitFunction(cstThisSub)
2594 End Function
' ScriptForge.SF_String.Wrap
2596 REM ============================================================= PRIVATE METHODS
2598 REM -----------------------------------------------------------------------------
2599 Private Function _Repr(ByRef pvString As String) As String
2600 ''' Convert an arbitrary string to a readable string, typically for debugging purposes (DebugPrint ...)
2601 ''' Carriage Returns are replaced by \r. Other line breaks are replaced by \n
2602 ''' Tabs are replaced by \t
2603 ''' Backslashes are doubled
2604 ''' Other non printable characters are replaced by \x00 to \xFF or \x0000 to \xFFFF
2605 ''' Args:
2606 ''' pvString: the string to make readable
2607 ''' Return:
2608 ''' the converted string
2610 Dim sString As String
' Return value
2611 Dim sChar As String
' A single character
2612 Dim lAsc As Long
' Ascii value
2613 Dim lPos As Long
' Position in sString
2616 ' Process TABs, CRs and LFs
2617 sString = Replace(Replace(Replace(pvString,
"\
",
"\\
"), SF_String.sfCR,
"\r
"), SF_String.sfTAB,
"\t
")
2618 sString = Join(SF_String.SplitLines(sString, KeepBreaks := False),
"\n
")
2619 ' Process not printable characters
2620 If Len(sString)
> 0 Then
2622 Do While lPos
<= Len(sString)
2623 sChar = Mid(sString, lPos,
1)
2624 If Not SF_String.IsPrintable(sChar) Then
2626 sChar =
"\x
" & Iif(lAsc
< 255, Right(
"00" & Hex(lAsc,
2)), Right(
"0000" & Hex(lAsc,
4)))
2627 If lPos
< Len(sString) Then
2628 sString = Left(sString, lPos -
1)
& sChar
& Mid(sString, lPos +
1)
2630 sString = Left(sString, lPos -
1)
& sChar
2633 lPos = lPos + Len(sChar)
2639 End Function
' ScriptForge.SF_String._Repr
2641 REM ================================================ END OF SCRIPTFORGE.SF_STRING