FWH1905: FW_AT() Case insensitive search

Post Reply
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

FWH1905: FW_AT() Case insensitive search

Post by nageswaragunupudi »

We frequently use the functions
AT( cSearch, cStr, [nFrom], [nEnd] ) // xHarbour
AT( cSearch, cStr ) // Harbour
HB_AT( cSearch, cStr, [nFrom], [nEnd] ) // Harbour

In many cases, we may need to convert both cSearch and cStr to Upper/Lower case for the search. Eg:

Code: Select all

? AT( Upper( cSearch ), Upper( cString ) )
 
FW_AT() primarily provides the same functionality as the (x)Harbour functions without the need for conversion of the strings to Upper/Lower case, by performing case insensitive search.

In addition, FW_AT() provides more capabilities that are not easily possible with (x)Harbour's AT() or HB_AT() except without tedious coding by the programmer.

Syntax:
FW_AT( acSearch, [@]cString, [ncFrom], [ncEnd], [lWholeWord], [lSkipQuotes], [@cMatchFound], [cSubstitute], [lAllMatches] ) --> nFoundAt/aFound


Parameters:
1. acSearch: (a) cSearch is the sub-string to find in cString
(b) Array of strings to find. In this case, the earliest position where one of the strings is matched is reported. This functionality is same as FWH function AAT( aSearch, cString ). In the case of an array, the last parameters cSubstitute and lAllMatches are ignored.

2. [@]cString: The string in which the match is to be found. When cReplace is specified, cString should be called by reference.

3. [[@]ncFrom]: Defaults to 1. The search starts from the position indicated by nFrom. The functionality is the same as HB_AT()
FWH1906: If a character string is specified and found in cString, the search starts from the character next to the match found. If not found, the search starts from the 1st position.

4. [[@]ncEnd]: Defaults to Len(cString): If a numeric value is specified, the search stops with the character at this position. Functionality is the same as HB_AT()
FWH1906: If a character string is specified and found in the cString, the search stops with the character before the match found. If not found, the search continues till the end of cString.

Code: Select all

   local cMatch, nAt
   local cnFrom   := "<test>"
   local cnEnd    := "</test>"
   local cReplace := "Examination"
   local cString  := "This test ok <test>any Test ok</test>one test ok"

   nAt := FW_AT( "TEST", @cString, @cnFrom, @cnEnd, nil, nil, @cMatch, cReplace )
   ? nAt, cnFrom, cnEnd, cMatch, cString //-->
   // 24, 20, 30, Test, 
   // This test ok <test>any Examination ok</test>one test ok
 
5. [lWholeWord]: Optional. Default .f.: If .t., only whole words are searched. The word can contain alphanumeric characters or "_".
Example:

Code: Select all

FW_AT( "ONE", "Stone Tone One Two" ) --> 3
FW_AT( "ONE", "Stone Tone One Two", nil, nil, .t. ) --> 12
 
6. [clSkipQuotes]: Optional. Default .f.: If .t., quoted text (between 2 double quotes, single quotes or []) is skipped while searching.
Exampe:

Code: Select all

FW_AT( "NEAR", [He said "it is near" but not really near] ) --> 16
FW_AT( "NEAR", [He said "it is near" but not really near], nil, nil, nil, .t. ) --> 37
 
FWH1905: Any character ', ", [ is considered to be the beginning of quoted text, till the matching unquote character, i.e., ', ", ] is found. This has a side-effect of treating apostrophe like ' in "David's" as beginning and end of the single-quoted text.

The behavior is same as the Harbour function ATSKIPSTRINGS().

FWH1906: Apostrophes are recognized wherever possible and not treated as beginning or end of single quotes. Still some cases like 'he is James' son' can mislead.

It is possible to specify a string containing which characters are to be treated as
starting quoted text. ["[] indicates that only " and [ are to be treated as beginning of quoted text. In this case ' is not considered as beginning or end of quoted text.

7. [@cMatch]: Optional: If specified, the exact match found is returned in the variable cMatch. Because the search is case insensitive, the case of the match may be different from cSearch.

Code: Select all

nAt := FW_AT( "ONE", "Stone Tone One Two", nil, nil, .t., nil, @cMatch )
? nAt, cMatch // 12, "One"
 
8. [cReplace]: Optional: If specified, the match found is substituted with this string. The substituted string can be shorter or longer. In this case, the 2nd parameter should be passed by reference. The search and substitution respects the parameters lWholeWord, lSkipQuotes and lAllMatches.

Code: Select all

cSearch := "ear"
cString := "Year Ear Hear"
nAt := FW_AT( cSearch, @cString, nil, nil, .t., .t., @cMatch, "Eye" )
? nAt, cMatch, cString // --> 6, Ear, Year Eye Hear
 
9. [lAllMatches]: Optional, Default .f.: Ignored when acSearch is an array. If .t., all maches of cSearch are found, respecting the conditions lWholeWord and lSkipStrings.
Returns a two-dimension array of positions of match and matches found. { { pos1, match1}, ...{ posN, matchN } }

If cReplace is specified, all matches are substituted with cReplace.

Code: Select all

   local cString  := "(SPRICE-PRICE)/Price*100"
   local aFields  := { "price,sprice" }
   local cField

   for each cField IN { "price" ,"sprice" }
      FW_AT( cField, @cString, nil, nil, .t., .f., nil, '::oRs:Fields( "' + cField + '" ):Value', .t. )
   next
   ? cString -->
   // (::oRs:Fields( "sprice" ):Value-::oRs:Fields( "price" ):Value)/::oRs:Fields( "price" ):Value*100
 
Regards

G. N. Rao.
Hyderabad, India
Post Reply