String: A sequence of characters // In MX, everything is stored as String.
One can either directly call _str* variables, or declare new "containers":
String zone = _str1;
double rugosite = Str.ToDouble(_str2);
If you need to go in past, you need to use:
_doJava.get("_str1", -x);
If not, the calculation is false when you are not in the treatment. It reads the lines which are only in the time treatment of your table.
Character
Testing whether a character is a number
Here we test whether the first character is a number
char carac = _str1.charAt(0);
if (carac >='0' && carac <='9' )
return "It's a number";
else
return "It's a character";
Testing if a variable is Numeric
if (Str.IsNumeric(_str1))
return _str1;
return "";
Converting to lowercase: .toLowerCase
String defect=_str1.toLowerCase();
Converting to uppercase: .toUpperCase
String defect=_str1.toUpperCase();
Length
Retrieving string length: .length
Returns an integer
return _str1.length();
Test the length
if (_str1.length()==10)
return "OK";
return "NOK";
It can be used as a number for a substring operation for example: (_str1.length()-4)
return _str1.substring(0,_str1.length());
To prepend a string with enough zeroes to get a fixed length: .SetLen0
Ex: Input string is "543" and a 5-character string is required (very useful for creating sorting indexes): Output is "00543"
String defect=Str.SetLen0(_str1,5);
Manipulation on substring
Extract part of a string: .substring
Le 1er parametre est inclu dans la substring. Le 2eme caractère est exclu.
if _str1 is a date such as yyyyMMdd_HHmmss:
Returning yyyy
return _str1.substring(0,4);
Returning MM
return _str1.substring(4,6);
Returning dd
return _str1.substring(6,8);
Returning HHmmss
return _str1.substring(9,15);
Extract part of a string: .Left / Right
if _str1 is a date such as yyyyMMdd_HHmmss:
return Str.Left(_str1,2);
return Str.Right(_str1,2);
Returning yy
Retrieving the last n characters of a string: .substring
For example the last 5
if (_str1.length()>=5)
return _str1.substring(_str1.length() - 5);
Split
Extract parts of a string: .split
we can separate all parts if the same character is used for separation
⚠️ split is not possible with the dot as separation, please replace it before with String new = _str1.replace(".","#"); for example
if _str1 is a date such as yyyy-MM-dd:
if (Str.CountWords(_str1,"-")<=2)
return "";
String[] parts = _str1.split("-");
String annee = parts[0];
String mois = parts[1];
String jour = parts [2];
return annee + mois + jour + "_000000";
// ==================================
// To make it works with a pipe "|", use regex see : java computing #45 in MX_DEALER1 Table Test
// ==================================
String[] parts = _str1.split("\\|");
String annee = parts[0];
String mois = parts[1];
String jour = parts [2];
return annee + mois + jour + "_000000";
// ==================================
// To make it works with an antislash
// ==================================
String path = _str1.replace('\\', '#');
if (Str.CountWords(path,"#")<=7)
return "";
String[] parts = path.split("#");
String nom = parts[8];
String step1 = Str.RemoveAfter(nom,".");
return step1;
doJava.get
Retrieve a value on another line: _doJava.get
Always put an index in the java if this operation is used, so as to provide a sorting order. This order is always from smallest to largest (or from oldest to most recent).
Previous line
if (_doJava.get("_str1",-1).length()==0) return "";
String previous=_doJava.get("_str1",-1);
Next line
if (_doJava.get("_str1",+1).length()==0) return "";
String next=_doJava.get("_str1",+1);
2 lines before
if (_doJava.get("_str1",-2).length()==0) return "";
String previous=_doJava.get("_str1",-2);
Contains
Test if a substring is in a string
_str1 can have G-11 / G-115 / 205R22 etc...
if(_str1.contains("-11")) return "G-11 Headlap";
if(_str1.contains("115")) return "G-115 GrayGreen";
if(_str1.contains("205")) return "G-205 Red";
if(_str1.contains("340")) return "G-340 Black";
if(_str1.contains("341")) return "G-341 Dark Gray";
Test if a pattern is in a string
You can use regular expressions to determine whether a pattern is found inside a string:
The following checks whether the string begins with an uppercase letter followed by a lowercase letter, two capital letters, an underscore, and a number.
if(_str1.matches("^[A-Z][a-z][A-Z][A-Z]_[0-9].*")) return _str1;
For example :
The previous code will find string looking like 'BcBB_2', 'FjGH_9' etc ...
Position and word counter
Position of a substring within a string: .indexOf
int i = _str1.indexOf("toto");
It also lets you determine whether a substring is present within the string
if (_str1.indexOf("toto")!= -1)
return "toto is in the phrase";
else
return "toto was not found within the phrase";
Counting the number of occurrences of a word: .CountWords
"_" in "75485_E_5553" would return "2"
return Str.CountWords(_str1,"_");
Replace
Replacing some characters by others and setting to lowercase (Ex: é to e, â to a, X to x, etc...): .toLowerCase
Be carefull ü, ö, ç and so on are not take into account here
String defaut=Str.RemoveAccent(_str1.toLowerCase(Locale.ENGLISH));
Replacing a character or substring with another: .replace
return _str1.replace("-","/");
Excel formula for Java operations (changing TAG names)
H16: New TAG
I16: Old TAG
="if (_str1.equals("""&H16&""")) return """&I16&""""&";"
Result:
if (_str1.equals("FOAMING_1_DEGASING_DURATION")) return "FOAMING_MOULD_CARIER_1_DEGASING_DURATION";
Remove basics
Removing a substring: .Remove
"AB" for exemple
String defect=Str.Remove(_str1, "AB");
Removing everything before a certain substring: .RemoveBefore
For example, "_" in "20151007_154300" returns "154300". Also works with several characters.
return Str.RemoveBefore(_str1,"_");
Nesting: If we want to extract "154300" from "2015_20151007_154300"
return Str.RemoveBefore(Str.RemoveBefore(_str1,"_"),"_");
To do the same thing, but while starting the search from the end of the string (ex: removing " " in order to transform "5.0 kg" into "kg"
return _str1.substring(_str1.lastIndexOf(" ")+1, _str1.length());
Removing everything after a certain substring: .RemoveAfter
For example, "_" in "20151007154300" returns "20151007".
Also works with several "" characters: With "20151007_154300_1G05", the result would also be "20151007"
return Str.RemoveAfter(_str1,"_");
To do the same thing, but while starting the search from the end of the string (ex: removing "_" and what follows in order to transform "H60640_J4_13-03-2017.txt" into "H60640_J4"
return part2.substring(0,part2.lastIndexOf("_"));
Remove for cleaning
Removing spaces before and after the substring
defaut = defaut.trim();
Removing double spaces from a string
"a b" --> "a b"
String text = _str1;
while(text.contains(" "))
{
text = text.replace(" ", " ");
}
return text;
Removing leading zeroes
Whatever the number of leading zeroes, we want to remove all of them. Example : "009990" --> "9990"
String var1 = _str1;
while (Str.Left(var1,1).equals("0"))
{
var1 = var1.substring(1, var1.length());
}
return var1;
// ================================
// New MX Common function
// ================================
return MxString_Remove_leading_zeroes(_doJava, _str1);
Remove numerical
Removing non-numerical characters: .RemoveNotNumeric
return Str.RemoveNotNumeric(_str1);
To also remove points ".":
return Str.Remove(Str.RemoveNotNumeric(_str1),".");
Removing everything after first non-numeric character
Example: "6728CA23.X" will return "6728"
int size = _str1.length();
char carac;
for(int i=0; i<size; i++){
carac = _str1.charAt(i);
if (carac >='0' && carac <='9' ){
}
else{
return Str.RemoveAfter(_str1,_str1.charAt(i));
}
}
return _str1;
// ==============================
// New MX Common function
// ==============================
/**
* Description : Removing everything after first non-numeric character
* Input : String _str1 : input string
* Output : String
*/
return MxString_Remove_after_first_nonnumeric_character(_doJava, _str1);
Return only last non-numeric characters
Example: "P18AJ" will return "AJ"
int size = _str1.length();
char carac;
for(int i=0; i<size; i++){
carac = _str1.charAt(i);
if (carac >='0' && carac <='9' )
return Str.RemoveBefore(_str1,_str1.charAt(i+1));
}
return "";
Hash string
Computing the hash of a string
If the only way to create a unique index by concatenating strings (in order to avoid using NoLineAndFile) results in a string longer than 255 characters, you're going to have problems.
You can hash it with MD5, which will result in a unique 32-character string as long as the input strings are unique.
// Instead of _str1 you can concatenate as many strings as you need
// (_str1 + _str... + ... )
String hashMe = _str1;
return StrGet.GetMD5(hashMe);
Input: "Numero de S/N : 214050" Output: "0301ce25cb425d415632422e9fb446b2"
Input: "Numero de S/N : 214051" Output: "06508267422732dc8f7752397cbeeec7"
You might be tempted to use _str1.hashCode(), which is built in, but which suffers from big collision problems: "Aa" and "BB" share the same hashCode (2112) for example. hashCode() was not designed for this.
Counting the number of different values in 8 variables
java.util.HashSet<String> hashSet=new java.util.HashSet<String>();
if (!_str1.equals(""))
hashSet.add(Str.RemoveAfter(_str1,"_"));
if (!_str2.equals(""))
hashSet.add(Str.RemoveAfter(_str2,"_"));
if (!_str3.equals(""))
hashSet.add(Str.RemoveAfter(_str3,"_"));
if (!_str4.equals(""))
hashSet.add(Str.RemoveAfter(_str4,"_"));
if (!_str5.equals(""))
hashSet.add(Str.RemoveAfter(_str5,"_"));
if (!_str6.equals(""))
hashSet.add(Str.RemoveAfter(_str6,"_"));
if (!_str7.equals(""))
hashSet.add(Str.RemoveAfter(_str7,"_"));
if (!_str8.equals(""))
hashSet.add(Str.RemoveAfter(_str8,"_"));
if(hashSet.size()==0)
return 0.0;
else
return Str.ToDouble(_str9)/hashSet.size();
To prepend a string with enough zeroes to get a fixed length = .SetLen0
Ex: Input string is "543" and a 5-character string is required (very useful for creating sorting indexes): Output is "00543"
String defect=Str.SetLen0(_str1,5);
Retrieving the last value of an Mx concatenation
/!\ Works only if each string is a character
Ex: Input is "A|B|C|D" and we want the "D":
if (_str1.indexOf("|")==-1) return _str1;
int i=(_str1.indexOf("|")*Str.CountWords(_str1,"|"))+Str.CountWords(_str1,"|");
return _str1.substring(i, _str1.length());
New solution :
String[] parts =_str1.split("\\|");
return parts[parts.length -1];
</source>
``` java
/**
* ============================
* MX New common function
* ============================
*
* Description : Retrieving the last value of an Mx concatenation with a pipe |
* Input : String _str1 : input string
* Output : String with last value of an Mx concatenation
*/
return MxString_Concat_last_value(_doJava, _str1);
Retrieving the value number i of an Mx concatenation
Ex: Input is "A_B_C_D" and we want "C":
if(_str1.length()==0) return "";
// Starts at 1 : First element is element number 1 (and not 0)
int element_number = 3;
String delimiter = "_";
if (_str1.contains(delimiter) && element_number >= 1)
{
String[] elements = _str1.split(java.util.regex.Pattern.quote(delimiter));
if(element_number - 1 < elements.length)
return elements[element_number - 1];
return "";
}
// If we get to here it's because the delimiter was not found,
// but we still want the first element.
// By default we return the content of _str1 (but you could choose "")
if(element_number == 1)
return _str1;
// No delimiter, and element number != 1 --> error.
return "";
/**
* ============================
* MX New common function
* ============================
*
* Description : Retrieving the i of an Mx concatenation
* Input : String _str1 : input string
* String _str2 : number i of element of Mx concatenation+
* String _str3 : Delimiter
* Output : String with i of an Mx concatenation
*/
// _str2 & _str3 are constants here
return MxString_Concat_element_i(_doJava, _str1, _str2, _str3);
// _str2 & _str3 must be set to whatever constant in order to make it work for now
return MxString_Concat_element_i(_doJava, _str1, "2", "_");
Sorted list of unique concatenation occurrences
Input : c|a|b|b|a|b|b|c
Output : a, b, c
Warning : This can take a lot of time to compute if you have many concatenated values. Please test before relying on this. DO NOT USE ON A LINE-BASED AGGREGATION, IT MAKES NO SENSE (a _doJava.get with a good order column is easier). ONLY USE ON A GPBYCOL CONCATENATION
if(_str1.equals("")) return "";
if(_str1.contains("|"))
{
TreeMap<String, String> tm = new TreeMap<>();
String[] elements = _str1.split(java.util.regex.Pattern.quote("|"));
for(int i = 0; i < elements.length; ++i)
{
tm.put(elements[i], Integer.toString(Str.CountMatches(_str1, elements[i])));
}
return Str.Remove(Str.Remove(tm.keySet().toString(), "["), "]");
}
return _str1;
ou return Str.Remove(Str.Remove(tm.keySet().toString(), "["), "]").replace(", ","|");
if you want replace , by |
/**
* ============================
* MX New common function
* ============================
* Description : Sorted list of unique concatenation occurences
* Input : String _str1
* Output : String _list : sorted list of unique concatenation occurences
*
* example input : c|a|b|b|a|b|b|c
* example output : a|b|c
*/
return MxString_Concat_Sorted_list_unique_concatenation_occurences(_doJava, _str1);
Number of unique concatenation occurrences
Input : c|a|b|b|a|b|b|c
Output : 3
Warning : This can take a lot of time to compute if you have many concatenated values. Please test before relying on this. DO NOT USE ON A LINE-BASED AGGREGATION, IT MAKES NO SENSE (a _doJava.get with a good order column is easier). ONLY USE ON A GPBYCOL CONCATENATION
if(_str1.equals("")) return "";
if(_str1.contains("|"))
{
TreeMap<String, String> tm = new TreeMap<>();
String[] elements = _str1.split(java.util.regex.Pattern.quote("|"));
for(int i = 0; i < elements.length; ++i)
{
tm.put(elements[i], Integer.toString(Str.CountMatches(_str1, elements[i])));
}
return tm.size();
}
return 1;
/**
* ============================
* MX New common function
* ============================
*
* Description : Number of unique concatenation occurences
* Input : String _str1
* Output : int number of unique occurence
*
* example input : c|a|b|b|a|b|b|c
* example output : 3
*/
return MxString_Concat_Number_unique_occurences(_doJava, _str1);
Most frequent occurrence
Input: a|b|b|c
Output (b is more frequent): b
Input: c|a|b|b|a|d|d|c
Output (each occurrence happens 2 times, and the last occurrence to occur 2 times was c.): c
Warning : This can take a lot of time to compute if you have many concatenated values. Please test before relying on this. DO NOT USE ON A LINE-BASED AGGREGATION, IT MAKES NO SENSE (a _doJava.get with a good order column is easier). ONLY USE ON A GPBYCOL CONCATENATION
if(_str1.equals("")) return "";
if(_str1.contains("|"))
{
TreeMap<Integer, String> tm = new TreeMap<>();
String[] elements = _str1.split(java.util.regex.Pattern.quote("|"));
for(int i = 0; i < elements.length; ++i)
{
tm.put(Str.CountMatches(_str1, elements[i]), elements[i]);
}
return tm.lastEntry().getValue();
}
return _str1;
Sorted list of unique concatenation occurrences, with number of occurrences
Input : c|a|b|b|a|b|b|c
Output : a=2, b=4, c=2
Warning : This can take a lot of time to compute if you have many concatenated values. Please test before relying on this. DO NOT USE ON A LINE-BASED AGGREGATION, IT MAKES NO SENSE (a _doJava.get with a good order column is easier). ONLY USE ON A GPBYCOL CONCATENATION
if(_str1.equals("")) return "";
if(_str1.contains("|"))
{
TreeMap<String, String> tm = new TreeMap<>();
String[] elements = _str1.split(java.util.regex.Pattern.quote("|"));
for(int i = 0; i < elements.length; ++i)
{
tm.put(elements[i], Integer.toString(Str.CountMatches(_str1, elements[i])));
}
return Str.Remove(Str.Remove(tm.toString(), "{"), "}");
}
return _str1;
/**
* ============================
* MX New common function
* ============================
*
* Description : Sorted list of unique concatenation with number of occurrences
* Input : String _str1
* Output : String _list : sorted list of unique concatenation occurrences with number of occurrences
*
* example input : c|a|b|b|a|b|b|c
* example output : a=2, b=4, c=2
*/
return MxString_Concat_Sorted_list_unique_with_number(_doJava, _str1);
Unsorted list of unique occurrence from another column
To create a list of unique occurrences in column _str2, when grouping for a given value of _str1.
(Group by _str1, "Values" options on _str2, but without repetitions).
Useful when needed for many variables, rendering Group by "Distinct consecutive" inapplicable.
if (_str1.equals(""))
return "";
if (_str1.equals(_doJava.get("_str1",1))) {
return ""; // Computation done only once per _str1 to save time and memory
}
else {
int i_row=1;
String list=_str2;
while (_str1.equals(_doJava.get("_str1",-i_row))) {
if (!list.contains(_doJava.get("_str2",-i_row))) {
list=list + "|" + _doJava.get("_str2",-i_row);
}
i_row=i_row+1;
}
return list;
}
Extract numerical values from a string
Extract numerical values from a string
Returns a string
Example for "SO22345"
return _str1.replaceAll("[^0-9]", "");
will return "22345"
Regexp
Extract a specific pattern
The example here is in order to find an information under the format "number-number-uppercase_letter" (e.g. "3-6-A"; "10-9-B"; ...) no matter the content.
java.util.regex.Pattern p; //declare Pattern
java.util.regex.Matcher m; //declare Matcher
p = java.util.regex.Pattern.compile("\\d*-\\d*-[A-Z]"); //declare your pattern
m = p.matcher(_str1); //test the pattern with your String
if(m.find()) return m.group(0); //test if there is a match
return "";
For testing and have more information on how regexp works : Regex101