Returning the string between the 5th and 6th Spaces in a String - substring

I have a column of strings that look like this:
Target Host: dcmxxxxxxc032.erc.nam.fm.com Target Name:
dxxxxxxgsc047.erc.nam.fm.com Filesystem /u01 has 4.98% available space
- fallen below warning (20) or critical (5) threshold.
The column name is [Description]
The substring I would like returned is (dxxxxxxgsc047.erc.nam.fm.com)
The only consistency in this data is that the desired string occurs between the 5th and 6th occurrences of spaces " " in the string, and after the phrase "Target Name: " The length of the substring varies, but it always ends in another " ", hence my attempt to grab the substring between the 5th and 6th spaces.
I have tried
MID([Description],((FIND([Description],"Target Name: "))+13),FIND([Description]," ",((FIND([Description],"Target Name"))+14)))
But that does not work.
(Edit: We use Tableau 8.2, the Tableau 9 only functions can't be part of the solution, thanks though!)
Thank you in advance for your help.

In Tableau 9 you can use regular expressions in formulas, it makes the task simpler:
REGEXP_EXTRACT([Description], "Target Name: (.*?) ")
Alternatively in Tableau 9 you can use the new FINDNTH function:
MID(
[Description],
FINDNTH([Description]," ", 5) + 1,
FINDNTH([Description]," ", 6) - FINDNTH([Description]," ", 5) - 1
)
Prior to Tableau 9 you'd have to use string manipulation methods similar to what you've tried, just need to be very careful with arithmetic and providing the right arguments (the third argument in MID is length, not index of the end character, so we need to subtract the index of the start character):
MID(
[Description]
, FIND([Description], "Target Name:") + 13
, FIND([Description], " ", FIND([Description], "Target Name:") + 15)
- (FIND([Description], "Target Name:") + 13)
)

Well, you need to find "Target name: " and then the " " after it, not so hard. I'll split in 3 fields just to be more clear (you can mix everything in a single field). BTW, you were in the right direction, but the last field on MID() should be the string length, not the char position
[start]:
FIND([Description],"Target name: ")+13
[end]:
FIND([Description]," ",[start])
And finally what you need:
MID([Description],[start]+1,[end]-[start]-1)
This should do. If you want to pursue the 5th and 6th " " approach, I would recommend you to find each of the " " until the 6th.
[1st]:
FIND([Description], " ")
[2nd]:
FIND([Description], " ",[1st] + 1)
And so on. Then:
MID([Description],[5th]+1,[6th]-[5th]-1)

A simple solution -
SPLIT( [Description], " ", 3 )
This returns a substring from the Description string, using the space delimiter character to divide the string into a sequence of tokens.
The string is interpreted as an alternating sequence of delimiters and
tokens. So for the string abc-defgh-i-jkl, where the delimiter
character is ‘-‘, the tokens are abc, defgh, i and jlk. Think of these
as tokens 1 through 4. SPLIT returns the token corresponding to the
token number. When the token number is positive, tokens are counted
starting from the left end of the string; when the token number is
negative, tokens are counted starting from the right. -
Tableau String Functions

I don't know Tableau, but perhaps something like this?
MID(
MID([Description], FIND([Description],"Target Name: ") + 13, 50),
1,
FIND(MID([Description], FIND([Description],"Target Name: ") + 13, 50), " ")
)

Related

Extract words in Lua split by Unicode spaces and control characters

I'm interested in a pure-Lua (i.e., no external Unicode library) solution to extracting the units of a string between certain Unicode control characters and spaces. The code points I would like to use as delimiters are:
0000-0020
007f-00a0
00ad
1680
2000-200a
2028-2029
202f
205f
3000
I know how to access the code points in a string, for example:
> for i,c in utf8.codes("Ê$ \tĪ€đŸ˜ƒ") do print(c) end
233
36
32
9
960
128515
but I am not sure how to "skip" the spaces and tabs and reconstitute the other codepoints into strings themselves. What I would like to do in the example above, is drop the 32 and 9, then perhaps use utf8.char(233, 36) and utf8.char(960, 128515) to somehow get ["Ê$", "Ī€đŸ˜ƒ"].
It seems that putting everything into a table of numbers and painstakingly walking through the table with for-loops and if-statements would work, but is there a better way? I looked into string:gmatch but that seems to require making utf8 sequences out of each of the ranges I want, and it's not clear what that pattern would even look like.
Is there a idiomatic way to extract the strings between the spaces? Or must I manually hack tables of code points? gmatch does not look up to the task. Or is it?
would require painstakingly generating the utf8 encodings for all code points at each end of the range.
Yes. But of course not manually.
local function range(from, to)
assert(utf8.codepoint(from) // 64 == utf8.codepoint(to) // 64)
return from:sub(1,-2).."["..from:sub(-1).."-"..to:sub(-1).."]"
end
local function split_unicode(s)
for w in s
:gsub("[\0-\x1F\x7F]", " ")
:gsub("\u{00a0}", " ")
:gsub("\u{00ad}", " ")
:gsub("\u{1680}", " ")
:gsub(range("\u{2000}", "\u{200a}"), " ")
:gsub(range("\u{2028}", "\u{2029}"), " ")
:gsub("\u{202f}", " ")
:gsub("\u{205f}", " ")
:gsub("\u{3000}", " ")
:gmatch"%S+"
do
print(w)
end
end
Test:
split_unicode("#\0#\t#\x1F#\x7F#\u{00a0}#\u{00ad}#\u{1680}#\u{2000}#\u{2005}#\u{200a}#\u{2028}#\u{2029}#\u{202f}#\u{205f}#\u{3000}#")

Split: A subscript must be between 1 and the size of the array

I have a super simple formula. The problem is that sometimes the data doesn't have a second value, or sometimes the value is blank.
Split ({PO_RECEIVE.VENDOR_LOT_ID}," ")[2]
ID
111 222
123
123 222
I was thinking if I could come up with some logic to figure out whether the string has multiple value's it would solve my problem, but haven't quiet found what I'm looking for:
If {PO_RECEIVE.VENDOR_LOT_ID} = SingleOrBlankString then
{PO_RECEIVE.VENDOR_LOT_ID} else
Split ({PO_RECEIVE.VENDOR_LOT_ID}," ")[2]
Better Example Data:
3011111*42011111111
2711 00291111111
711111//12111111111
/J1111 69111111111
170111
If the string can contain a maximum of two values, separated by a space, then you can check if the string contains a space using the InStr function:
If InStr({PO_RECEIVE.VENDOR_LOT_ID}, " ") > 0 Then
{PO_RECEIVE.VENDOR_LOT_ID}
Else
Split ({PO_RECEIVE.VENDOR_LOT_ID}," ")[2]
If there can be multiple spaces between the parts you can use following formulas to get the values:
Left part:
This function returns the left part of the string until the first space.
If InStr({PO_RECEIVE.VENDOR_LOT_ID}, " ") > 0 Then
Left({PO_RECEIVE.VENDOR_LOT_ID}, InStr({PO_RECEIVE.VENDOR_LOT_ID}, " "))
Right part:
This function returns the right part of the string after the last space.
The InStrRev-function returns the position of the last space because it searches the string backwards.
The Len-function returns the length of the string.
[length] - [position of last space] = [length of the right part]
If InStr({PO_RECEIVE.VENDOR_LOT_ID}, " ") > 0 Then
Right({PO_RECEIVE.VENDOR_LOT_ID}, Len({PO_RECEIVE.VENDOR_LOT_ID}) - InStrRev(testString, " "))

Remove Currency Symbol

My selection formula it works fine, but it shows a $ symbol before amounts. How can I remove this?
if {tblComparativeBalance.iAcctLevel} - {##highest_level} = 0
then if Sum ({tblComparativeBalance.mBalance_amt0}, {tblComparativeBalance.sAccount_cd}) > 0
then ToText(Sum ({tblComparativeBalance.mBalance_amt0}, {tblComparativeBalance.sAccount_cd}),2)
else "(" + ToText(abs(Sum ({tblComparativeBalance.mBalance_amt0}, {tblComparativeBalance.sAccount_cd})),2) + ")"
else ""
You have to right-click on this formula field on your layout, then choose Format Field...
In the number tab, un-check the Display Currency Symbol, then click OK
But since in your formula you are converting it to string, you have to edit your formula to the following:
ToText(Sum ({tblComparativeBalance.mBalance_amt0},{tblComparativeBalance.sAccount_cd}),2, "")
The last parameter is the Character of the Currency symbol, so in this case you are setting it to empty, means no currency symbol.
Same thing is applied to the else formula.
"(" + ToText(abs(Sum ({tblComparativeBalance.mBalance_amt0}, {tblComparativeBalance.sAccount_cd})),2, "") + ")"
If you need to remove it from Strings, you can use:
REPLACE( {yourStringHere} ,"$","")
Convert the number to number first, then text:
ToText(ToNumber({YOUR_VALUE}))````

Crystal Reports find the first 3 words of a string

I have a database field with strings like this
oh the sea OToole was right
I like ramen but
Rowing like a Blue but not an artist
They are actual words separated with space
I want to find to extract the first 3 words
The result would be like below
oh the sea
I like ramen
Rowing like a
I tried the following
ExtractString({tbname.field1},""," ") & " " & ExtractString({tbname.field1}," "," ") & ExtractString({tbname.field1}," "," ")
It did work for the the first two fields but not the second
I tried the one below too
split({tbname.field1}, " ")[1] & " " & split({tbname.field1}, " ")[2]
& " " & split({tbname.field1}, " ")[3]
It gives me an error saying the indice must be between 1 and the size of the array
Any insights are more than welcome
if ubound(Split({tbname.field1})) < 3 then
Join(Split({tbname.field1})[1 to ubound(Split({tbname.field1}))]," ")
else Join(Split({tbname.field1})[1 to 3]," ")
** edited to reflect data is contained in a single row, rather than 3 separate rows
Try:
// defined delimiter
Local Stringvar CRLF := Chr(10)+Chr(13);
// split CRLF-delimited string into an array
Local Stringvar Array rows := Split({Command.WORDS}, CRLF);
// the results of all the work
Local Stringvar Array results;
// process each 'row'
Local Numbervar i;
for i := 1 to ubound(rows) do (
// increment the array, then add first 3 words
Redim Preserve results[Ubound(results)+1];
results[ubound(results)]:=Join(Split(rows[i])[1 to 3]," ")
);
// create CRLF-delimited string
Join(results, CRLF);

Format a variable in iReport in a string with multiple fields

I have a text field that has the following expression:
$F{casNo} + " Total " + $P{chosenUom} + ": " + $V{total_COUNT}
casNo is a string, chosenUom is a string. total_COUNT is a sum variable of doubles. The total_COUNT variable displays, but it's got 8 - 10 decimal places (1.34324255234), all I need is something along the lines of 1.34.
Here's what I tried already:
$F{casNo} + " Total " + $P{chosenUom} + ": " + new DecimalFormat("0.00").format($V{total_COUNT}).toString()
Any help would be appreciated
For now I'm just doing basic math, but I'm hoping for a real solution, not a workaround
((int)($V{total_COUNT}*100.0))/100.0
You can format the in lline numbers by using:
new DecimalFormat("###0.00").format(YOUR NUMBER)
You might split the text field into two, one containing everything but the $V{total_COUNT}, and the second containing only $V{total_COUNT}, but with the Pattern property set to something like "#0.00".
You'd have to get a bit creative with layout, though, to prevent unwanted word-wrapping and spacing; for example, first text field could be wide and right-aligned, while text field containing the count could be left-aligned and wide enough to accommodate the formatted number.