Files
tasks/programe/regex.prg
2026-04-21 15:46:20 +03:00

160 lines
4.7 KiB
Plaintext

*!* CLEAR
*!* ?strtranx([ana are 1234567890.1234 lei], [\s\d+\.\d\s], [=TRANSFORM($1, "999 999 999 999.99")])
*?strtranx([ana are <<1234567890.1234>> lei], [<<], [=TRANSFORM($1, "AA")])
*!* RETURN
*-- http://www.cornerstonenw.com/article_id_parsing3.htm
*-- count words
? OccursRegExp("\b(\w+)\b", [the then quick quick brown fox fox])
&& prints 7
*-- count repeatedwords
? OccursRegExp("\b(\w+)\s\1\b", [the then quick quick brown fox fox])
&& prints 2
*-- replace first and second lower-case "a"
? strtranx([Abracadabra],[a],[*],1,2)
&& prints Abr*c*dabra
*-- replace first and second "a" case-insensitive
? strtranx([Abracadabra],[a],[*],1,2,1)
&& prints *br*cadabra
*-- locate the replacement targets
? strtranx([Abracadabra],[^a|a$],[*],1,2,0)
&& Abracadabr*
? strtranx([Abracadabra],[^a|a$],[*],1,2,1)
&& *bracadabr*
lcText = "The cost, is $123,345.75. "
*-- convert the commas
lcText = strtranx( m.lcText, "(\d{1,3})\,(\d{1,}) ","$1 $2" )
*-- convert the decimals
? strtranx( m.lcText, "(\d{1,3})\.(\d{1,})", "$1,$2" )
** prints "The cost, is $123 345,75."
*-- add 1 to all digits
? strtranx( [ABC123], "(\d)", [=TRANSFORM(VAL($1)+1)] )
** prints "ABC234"
*-- convert all dates to long format
? strtranx( [the date is: 7/18/2004 ] , [(\d{1,2}/\d{1,2}/\d{4})], [=TRANSFORM(CTOD($1),"@YL")])
** prints "the date is: Sunday, July 18, 2004"
*----------------------------------------------------------
FUNCTION StrtranRegExp( tcSourceString, tcPattern, tcReplace )
LOCAL loRE
loRE = CREATEOBJECT("vbscript.regexp")
WITH loRE
.PATTERN = tcPattern
.GLOBAL = .T.
.multiline = .T.
RETURN .REPLACE( tcSourceString , tcReplace )
ENDWITH
ENDFUNC
*----------------------------------------------------------
FUNCTION OccursRegExp(tcPattern, tcText)
LOCAL loRE, loMatches, lnResult
loRE = CREATEOBJECT("vbscript.regexp")
WITH loRE
.PATTERN = m.tcPattern
.GLOBAL = .T.
.multiline = .T.
loMatches = loRE.Execute( m.tcText )
lnResult = loMatches.COUNT
loMatches = NULL
ENDWITH
RETURN m.lnResult
ENDFUNC
*----------------------------------------------------------
FUNCTION strtranx(tcSearched, ;
tcSearchFor, ;
tcReplacement, ;
tnStart, tnNumber, ;
tnFlag )
*-- the final version of the UDF
LOCAL loRE, lcText, lnShift, lcCommand,;
loMatch, loMatches, lnI, lnK, lcSubMatch,;
llevaluate, lcMatchDelim, lcReplaceText, lcReplacement,;
lnStart, lnNumber, loCol, lcKey
loRE = CREATEOBJECT("vbscript.regexp")
WITH loRE
.PATTERN = m.tcSearchFor
.GLOBAL = .T.
.multiline = .T.
.ignorecase = IIF(VARTYPE(m.tnFlag)=[N],m.tnFlag = 1,.F.)
ENDWITH
lcReplacement = m.tcReplacement
*--- are we evaluating?
IF m.lcReplacement = [=]
llevaluate = .T.
lcReplacement = SUBSTR( m.lcReplacement, 2 )
ENDIF
IF VARTYPE( m.tnStart )=[N]
lnStart = m.tnStart
ELSE
lnStart = 1
ENDIF
IF VARTYPE( m.tnNumber) =[N]
lnNumber = m.tnNumber
ELSE
lnNumber = -1
ENDIF
IF m.lnStart>1 OR m.lnNumber#-1 OR m.llevaluate
lcText = m.tcSearched
lnShift = 1
loMatches = loRE.execute( m.lcText )
loCol = CREATEOBJECT([collection])
lnNumber = IIF( lnNumber=-1,loMatches.COUNT,MIN(lnNumber,loMatches.COUNT))
FOR lnK = m.lnStart TO m.lnNumber
loMatch = loMatches.ITEM(m.lnK-1) && zero based
lcCommand = m.lcReplacement
FOR lnI= 1 TO loMatch.submatches.COUNT
lcSubMatch = loMatch.submatches(m.lnI-1) && zero based
IF m.llevaluate
* "escape" the string we are about to use in an evaluation.
* it is important to escape due to possible delim chars (like ", ' etc)
* malicious content, or VFP line-length violations.
lcKey = ALLTRIM(TRANSFORM(m.lnK)+[_]+TRANSFORM(m.lnI))
loCol.ADD( m.lcSubMatch, m.lcKey )
lcSubMatch = [loCol.item(']+m.lcKey+[')]
ENDIF
lcCommand = STRTRAN( m.lcCommand, "$" + ALLTRIM( STR( m.lnI ) ) , m.lcSubMatch)
ENDFOR
IF m.llevaluate
TRY
lcReplaceText = EVALUATE( m.lcCommand )
CATCH TO loErr
lcReplaceText="[[ERROR #"+TRANSFORM(loErr.ERRORNO)+[ ]+loErr.MESSAGE+"]]"
ENDTRY
ELSE
lcReplaceText = m.lcCommand
ENDIF
lcText = STUFF( m.lcText, loMatch.FirstIndex + m.lnShift, m.loMatch.LENGTH, m.lcReplaceText )
lnShift = m.lnShift + LEN( m.lcReplaceText ) - m.loMatch.LENGTH
ENDFOR
ELSE
lcText = loRE.REPLACE( m.tcSearched, m.tcReplacement )
ENDIF
RETURN m.lcText
ENDFUNC