TradingView
PineCoders
22 Jan 2021 pukul 15.13

String Manipulation Framework [PineCoders FAQ] 

JAPANESE YEN / U.S. DOLLARICE

Deskripsi

█ OVERVIEW

This script provides string manipulation functions to help Pine coders.
                                
                              
█ FUNCTIONS PROVIDED

f_strLeft(_str, _n)

Function returning the leftmost `_n` characters in `_str`.

f_strRight(_str, _n)

Function returning the rightmost `_n` characters in `_str`.

f_strMid(_str, _from, _to)

Function returning the substring of `_str` from character position `_from` to `_to` inclusively.

f_strLeftOf(_str, _of)

Function returning the sub-string of `_str` to the left of the `_of` separating character.

f_strRightOf(_str, _of)

Function returning the sub-string of `_str` to the right of the `_of` separating character.

f_strCharPos(_str, _chr)

Function returning the position of the first occurrence of `_chr` in `_str`, where the first character position is 0. Returns -1 if the character is not found.

f_strReplace(_src, _pos, _str)

Function that replaces a character at position `_pos` in the `_src` string with the `_str` character or string.

f_tickFormat()

Function returning a format string usable with `tostring()` to round a value to the symbol's tick precision.

f_tostringPad(_val, _fmt)

Function returning a string representation of a numeric `_val` using a special `_fmt` string allowing all strings to be of the same width, to help align columns of values.

`f_tostringPad()`
Using the functions should be straightforward, but `f_tostringPad()` requires more explanations. Its purpose is to help coders produce columns of fixed-width string representations of numbers which can be used to produce columns of numbers that vertically align neatly in labels, something that comes in handy when, for example, you need to center columns, yet still produce numbers of various lengths that nonetheless align.

While the formatting string used with this function resembles the one used in tostring(), it has a few additional characteristics:
 • The question mark (" ? ") is used to indicate that padding is needed.
 • If negative numbers must be handled by the function, the first character of the formatting string must be a minus sign ("-"),
  otherwise the unary minus sign of negative numbers will be stripped out.
 • You will produce more predictable results by using "0" rather than "#" in the formatting string.

You can experiment with `f_tostringPad()` formatting strings by changing the one used in the script's inputs and see the results on the chart.
These are some valid examples of formatting strings that can be used with `f_tostringPad()`:
"???0": forces strings to be four units wide, in all-positive "int" format. "-???0": forces strings to be four units wide, plus room for a unary minus sign in the first position, in "int" format. "???0.0": forces strings to be four units wide to the left of the point, all-positive, with a decimal point and then a mantissa rounded to a single digit. "-???0.0?": same as above, but adds a unary minus sign for negative values, and adds a space after the single-digit mantissa. "?????????0.0": forces the left part of the float to occupy the space of 10 digits, with a decimal point and then a mantissa rounded to a single digit.



█ CHART

The information displayed by this indicator uses the values in the script's Inputs, so you can use them to play around.
The chart shows the following information:
 • Column 0: The numeric input values in a centered column, converted to strings using tostring() without a formatting argument.
 • Column 1: Shows the values formatted using `f_tostringPad()` with the formatting string from the inputs.
 • Column 2: Shows the values formatted using `f_tostringPad()` but with only the part of the formatting string left of the decimal point, if it contains one.
 • Column 3: Shows the values formatted using `f_tostringPad()` but with the part of the formatting string left of the decimal point,
  to which is added the right part of the `f_tostringPad()` formatting string, to obtain the precision in ticks of the symbol the chart is on.
 • Column 4: Shows the result of using the other string manipulation functions in the script on the source string supplied in the inputs.
  It also demonstrates how to split up a label in two distinct parts so that you can vertically align columns when the leftmost part contains strings with varying lengths.
  You will see in our code how we construct this column in two steps.


█ LIMITATIONS

The Pine runtime is optimized for number crunching. Too many string manipulations will take a toll on the performance of your scripts, as can readily be seen with the running time of this script. To minimize the impact of using string manipulation functions in your scripts, consider limiting their calculation to the first or last bar of the dataset when possible. This can be achieved by using the var keyword when declaring variables containing the result of your string manipulations, or by enclosing blocks of code in if blocks using barstate.isfirst or barstate.islast.


█ NOTES

To understand the challenges we face when trying to align strings vertically, it is useful to know that:
 • As is the case in many other places in the TadingView UI and other docs, the Pine runtime uses the MS Trebuchet font to display label text.
 • Trebuchet uses proportionally-spaced letters (a "W" takes more horizontal space than an "I"), but fixed-space digits (a "1" takes the same horizontal space as a "3").
  Digits all use a figure space width, and it is this property that allows us to align numbers vertically.
  The fact that letters are proportionally spaced is the reason why we can't vertically align columns using a "legend" + ":" `+ value structure when the "legend" part varies in width.
 • The unary minus sign is the width of a punctuation space. We use this property to pad the beginning of numbers
  when you use a "-" as the first character of the `f_tostringPad()` formatting string.

Our script was written using the PineCoders Coding Conventions for Pine.
The description was formatted using the techniques explained in the
PineCoders publication.


█ THANKS

Thanks to LonesomeTheBlue for the `f_strReplace()` function.



Look first. Then leap.

Komentar
avmarko
Great work!
Is there any way to get the result as a "simple" string instead of "string series" (need to use "f_strMid" to return a substring for use with "security"). Thanks in advance
PineCoders
@avmarko

Hi 👋, the majority of the functions included in this publication have been superseded with advancements in Pine within the `str` name space. You can now use str.substring() in place of `f_strMid()`, which can return "simple" string, if the supplied source is "simple" form. There is a use case example in the refman entry at the above link.

The release of these functions were highlighted in this blog post.

If you would like to know about Pine Script updates, check out the Release notes section. The PineCoders account also broadcasts updates on its Squawk Box Telegram channel, Twitter and the Pine Script public chat on TradingView.

Cheers and happy coding.
avmarko
@PineCoders, thanks!
After switching the script to v5, I used str.substr() which does return simple string :-)
PineCoders
@avmarko, We are happy to help when we can! All the best 💚
intergoro
Hi, sorry for disturbing.
I would like to understand how can I define a number with fixed length on both sides of the "dot", namely for both the integer and decimal part.
You defined a function doing this job with the "tick precision" but I would like something to be independent of the precision.
An example is to choose a format like this "####.####" and convert all the possible numbers to a string with this fixed format (if they do not fit they get rounded),
like 1234.56789 ---> "1234.5679" or 23.56 ---> "0023.5600". Is it possibile? Thank you so much for your help
GETpacman
@PineCoders any chance this script be also made available as v5 library?
GETpacman
@PinceCoders, I was looking for string framework and found yours to be one stop solution. I needed a v5 library and there wasn't one. So I spent some time converting your code to v5 with minimal changes.

the code is published here and happy to be taken off into your repo.

tradingview.com/script/wHnRgeTb-smf/
ParabolicValue
@PineCoders If I choose to perform several string manipulations in an if block, what is the limiting factor? Am I limited to 200ms for the if block? I'm pretty sure one search and replace function already will use up the whole 200ms...
PineCoders
@ParabolicValue, Hi, The 200ms limit applies only to local blocks of each individual loop in your code — not to other local blocks such as those of conditional structures like `if`. The limiting factor in your case thus becomes the 40sec total execution time for the script.
ParabolicValue
Hello,
I'm implementing the any alert() function call feature into my alerts, and I'm using user inputs for the alert messages. How can I add a line break in the alert message?
I'm imagining using a JSON {{br}} to break the line when setting up the alert message. I just need a way to define br as a line break.
Any ideas?
Lebih lanjut