1

I need to display an output from a data record that is formatted similar to this: XXXX:12345 (Xxxxxxxxx)

However, the only data I want to output is the "12345" and with two preceding zeros, i.e. the output should look like "0012345". The "12345" in the record is example only, each record has a unique number assigned. An example record looks like this: CAST:98765 (RPOS1234-XY)

Can I use the ReplaceNoCase() to pull only that data out of the record? If so, how would I write the code to remove the unwanted characters?

  • What are the `XX`s supposed to represent? Can they be numbers? – Digital Chris Jan 15 '15 at 14:11
  • 1
    Also, is there some reason the answer needs to use `ReplaceNoCase()` as opposed to, say, [`REReplaceNoCAse()`](http://help.adobe.com/livedocs/coldfusion/8/htmldocs/help.html?content=functions_m-r_35.html)? – Digital Chris Jan 15 '15 at 14:13
  • The first set of XXXX is actually the word "CAST", the last set of (Xxxxxxxxx) within the parens are variable in length and contain both alpha numeric characters. Does not have to be ReplaceNoCase(). – Cajun WebDev Jan 15 '15 at 14:15
  • Have not looked at the ListToArray function, but the "12345" is example only, all records will have a unique number. – Cajun WebDev Jan 15 '15 at 14:25
  • *with two preceding zeros* Do you mean pad the extracted number with zeroes? Also, what have you tried so far? – Leigh Jan 15 '15 at 15:10
  • For what it's worth, both answers look valid, but coldfusion's several easily accessible list functions make parsing simple-pattern strings easy and very very readable. If it produces the result you want, I'd suggest Scott's answer. – Regular Jo Jan 15 '15 at 15:58
  • @cfqueryparam I considered a one line solution using `listGetAt` or even better regex-based, but I wanted to consider the audience and code maintainability. – Digital Chris Jan 15 '15 at 16:50

3 Answers3

4

You can do this in one line of code using a few functions.

str = 'CAST:98765 (RPOS1234-XY)';
projectCode = '00' & listLast( listFirst( str, ' ' ), ':' );

writeDump( projectCode );

To explain this code from the inner most function going out.

ListFirst() gets the first element in an a list based on the delimiter you specify, in this case the delimiter is ' ' - a space - yes, you can use a space as a delimiter.

ListLast() gets the last element in a list based on the delimiter you specify, in this case the delimiter is ':'

The first part simplt appends '00' to the result of the above function calls.

Scott Stroz
  • 7,510
  • 2
  • 21
  • 25
  • Of course, if the syntax of the string changes, so might the above code need to be changed. – Scott Stroz Jan 15 '15 at 15:14
  • 3
    Or use multiple delimiters. Then it is a single list function call to get the raw value ie `getToken(text, 2, ":(")`. Trim it if you do not want the trailing space. – Leigh Jan 15 '15 at 15:18
  • I can never remember to use `getToken()`. Good call. – Scott Stroz Jan 15 '15 at 15:30
  • 2
    Actually, you can use `getToken( str, 2, ": ")` and it takes care of the trailing space. – Scott Stroz Jan 15 '15 at 15:31
  • @scott-stroz This works! Thanks so much! I changed up the code a bit to fit the needs of the data and output, but this resolved the issue! castTicket = projectCode; castNumber = '00' & listLast( listFirst( castTicket, ' ' ), ':' ); #castNumber# – Cajun WebDev Jan 15 '15 at 20:55
2

If I had to use reReplaceNoCase or reFindNoCase this is how I would do it.

function parseTokenUsingReFindNoCase(token) {
    var local = {};

    // use regex to locate position of number (see only set of parentheses in regex pattern)
    local.positions = reFindNoCase("^.+:(\d+).+$", arguments.token, 1, true);
    // obtain the token substring and ensure at least 7 digits with preceding 0's
    local.result = numberFormat( mid(arguments.token, local.positions.pos[2], local.positions.len[2]), repeatString(0, 7));

    return local.result;
}


function parseTokenUsingReReplaceNoCase(token) {
    var local = {};

    // use regex to strip away text before and after the token
    local.result = reReplaceNoCase(arguments.token, "(^\D+|\s.+$)", "", "all");
    // ensure at least 7 digits with preceding 0's
    local.result = numberFormat(local.result, repeatString(0, 7));

    return local.result;
}

<h1>ParseToken</h1>

<h2>Using ReFindNoCase</h2>
<cfdump var="#parseTokenUsingReFindNoCase("CAST:98765 (RPOS1234-XY)")#" /><br>
<cfdump var="#parseTokenUsingReFindNoCase("CAST:591498 (FUBAR56-XE)")#" /><br>
<cfdump var="#parseTokenUsingReFindNoCase("CAST:784 (RFP4542-LL)")#" /><br>

<h2>Using ReReplaceNoCase</h2>
<cfdump var="#parseTokenUsingReReplaceNoCase("CAST:98765 (RPOS1234-XY)")#" /><br>
<cfdump var="#parseTokenUsingReReplaceNoCase("CAST:591498 (FUBAR56-XE)")#" /><br>
<cfdump var="#parseTokenUsingReReplaceNoCase("CAST:784 (RFP4542-LL)")#" /><br>

ParseToken

Using ReFindNoCase

  • 0098765
  • 0591498
  • 0000784

Using ReReplaceNoCase

  • 0098765
  • 0591498
  • 0000784
1

It doesn't use replaceNoCase, but based on your comments this will work:

<cfset castTicket = projectCode>
  <!--- strip the first 5 characters, since it is always "CAST " --->
<cfset castTicket = removechars(castTicket, 1,5)>
  <!--- now return the leftmost characters, up to the space --->
<cfset castTicket = left(castTicket, find(" ", castTicket) )>  
  <!--- format the number so it has 7 digits (2 leading zeros in this case) --->
<cfset castTicket = NumberFormat(castTicket, 0000000)>
<cfoutput>#castTicket#</cfoutput>

Returns:

0012345

Digital Chris
  • 6,177
  • 1
  • 20
  • 29
  • the actual data tag is #projectCode#, so am I correct in that the first line in your example should be: – Cajun WebDev Jan 15 '15 at 14:35
  • Then just change the first line to be `` – Digital Chris Jan 15 '15 at 14:37
  • @CajunWebDev Notice how Chris didn't use `"##"` to set the variable. When you're setting a variable the pound signs are almost never needed – Matt Busche Jan 15 '15 at 14:51
  • I get the following error: The 2 parameter of the Left function, which is now 0, must be a positive integer – Cajun WebDev Jan 15 '15 at 15:27
  • That makes me think there is no space after the number and before the `(`... could that be? – Digital Chris Jan 15 '15 at 15:33
  • This is how my code is set now which is giving the "2 parameter of the Left function, which is now 0, must be a positive integer" error: #castTicket# – Cajun WebDev Jan 15 '15 at 15:40
  • This is wrong: `` It sets the variable to literally be "projecCode" (the string). Use `` – Digital Chris Jan 15 '15 at 15:41
  • @Digital-Chris I am still getting the "2 parameter of the Left function, which is now 0, must be a positive integer" error. However, when I change this line to: my output is something like this: 0000008 – Cajun WebDev Jan 15 '15 at 18:36
  • (Edit) @CajunWebDev - Then the strings you are using are different than what you described ie note the space `XXXX:12345(space)(Xxxxxxxxx)`. String matching is all about identifying patterns. Will the strings *always* be in format `x`, are spaces optional, etc... ? In order to construct the proper code, you need to identify the patterns first. So it is important to provide samples that *accurately* reflect the strings you are working with. – Leigh Jan 15 '15 at 20:39
  • @CajunWebDev you can `#castTicket#` after every line and make sure you are getting what you expect to get... – Digital Chris Jan 15 '15 at 20:47