Data validation with RegEx on time-formatted cell - regex

I need to validate time entered in a cell. But the cell HAS to be in date format because I will need it later to extract hours and minutes.
My RegEx will check perfectly if the cell format is plain text, but if I set it to "time" or "date" or "hh:MM", I get an error in the Spreadsheet : "Parameter 1 expects text, but 0.52154 is number type and can't be forced to text type" (approximate translation from French, sorry).
My formula :
=REGEXMATCH(F5,"([0-1][0-9]:[0-5][0-9]:[0-5][0-9])?([0-9]:[0-5][0-9]:[0-5][0-9])?([0-1][0-9]:[0-5][0-9])?([0-9]:[0-5][0-9])?")
Is there a workaround ?

You could convert number to text with formula:
=REGEXMATCH(TEXT(F5,"hh:mm:ss"),regex)
hh:mm:ss converts the number into proper sting that mimics time format.
to make sure, that entered time is in number format, you should also use ISNUMBER function:
=and(ISNUMBER(F5),REGEXMATCH(TEXT(F5,"hh:mm:ss"),regex)
will return false if text was entered.

The value reads:
Function REGEXMATCH parameter 1 expects text values. But '123' is a number and cannot be coerced to a text.
You get an error because a regex cannot be applied to values other than text. Cast the value to text and use the REGEXMATCH:
=REGEXMATCH(TEXT(F5,""),"([0-1][0-9]:[0-5][0-9]:[0-5][0-9])?([0-9]:[0-5][0-9]:[0-5][0-9])?([0-1][0-9]:[0-5][0-9])?([0-9]:[0-5][0-9])?")
^^^^^^^^^^^

Searching and testing again, I came across a variation of the =TEXT(A1,"pattern") formula : = TO_TEXT()
My final formula :
=REGEXMATCH(TO_TEXT(E20);"([0-1][0-9]:[0-5][0-9]:[0-5][0-9])|([0-9]:[0-5][0-9]:[0-5][0-9])|([0-1][0-9]:[0-5][0-9])|([0-9]:[0-5][0-9])")
I must dig a little bit to understand the difference between TO_TEXT() and TEXT()...
The issue was definitely the way you have to format the pattern parameter of the function. If something like 12h45 was entered, the =TEXT(E20;"hh:mm:ss") pattern would return 00:00:00, and the regex would be evaluated as TRUE.

Related

Extract Specific Parameter value using Regex Postgresql

Given input string as
'PARAM_1=TRUE,THRESHOLDLIST=kWh,2000,Gallons,1000,litre,3000,PARAM_2=TRUE,PARAM_3=abc,123,kWh,800,Gallons,500'
and unit_param = 'Gallons'
I need to extract value of unit_param (Gallons) which is 1000 using postgresql regex functions.
As of now, I have a function that first extracts value for THRESHOLDLIST which is "kWh,2000,Gallons,1000,litre,3000", then splits and loops over the array to get the value.
Can I get this efficiently using regex.
SELECT substring('PARAM_1=TRUE,THRESHOLDLIST=kWh,2000,Gallons,1000,litre,3000,PARAM_2=TRUE,PARAM_3=abc,123,xyz' FROM '%THRESHOLDLIST=#".........#",%' FOR '#')
Use substring() with the target input grouped:
substring(myCol, 'THRESHOLDLIST=[^=]*Gallons,([0-9]+)')
The expression [^=]* means “characters that are not =”, so it won’t match Gallons within another parameter.
select
Substring('PARAM_1=TRUE,THRESHOLDLIST=kWh,2000,Gallons,1000,litre,3000,PARAM_2=TRUE,PARAM_3=abc,123,xyz' from 'Gallons,\d*');
returns Gallons,1000

Remove space from numbers - Leave rest intact

Full disclosure: I'm no programmer (which will probably be evident in a second). I frequently copy numbers from one sheet to another and numbers bigger than 999 have a space between the first and the second number. I have tried to make script (with help from similar scripts I've found here) that remove these spaces at the click of a button but it only kinda works.
Here's a sample sheet with my code included: https://docs.google.com/spreadsheets/d/11_CWZfhBupUpBKYi7I9cwGBakSr4LikOm0bGft6YA7Q/edit?usp=sharing
I have tried my best to modify the Regex-expression to do what I want but I guess my knowledge is just too poor.
....
function Remove_space() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Input");
var r = sheet.getRange("E4:E50");
var v = r.getValues();
for(var k=0;k<v.length;k++)
for(var j=0;j<v[0].length;j++)
v[k][j]=v[k][j].toString().replace(/\s/g, "");
r.setValues(v);
};
....
Can anyone help me out and make the spaces go away but leave my commas intact?
It does remove the spaces but for some reason it also converts my commas (decimal separator) into periods. If there are no decimals it's no problem.
Issue:
String conversion: Javascript doesn't support , as decimal separator. So, when you getValue(), they're automatically converted to .. When you setValue(), it'll be converted back to ,. But during the execution of the function, you use .toString(), which makes the period . permanent.
Solution:
Get as String type: Use getDisplayValues() if you want to get numbers as strings with , as decimal separator intact. OR
Set as Number type: Convert the regex replaced string back to a number. You should also manually convert comma , to period . in this case to cast it back to number type.
Snippet:
r.getDisplayValues();
OR
v[k][j]=Number(v[k][j].toString().replace(/\s/g, "").replace(/\,/g,"."));
References:
Number
Range#getDisplayValues: Notice that it returns String [], whereas getValues() returns Object []

OpenRefine custom text faceting

I have a column of names like:
Quaglia, Pietro Paolo
Bernard, of Clairvaux, Saint, or
.E., Calvin F.
Swingle, M Abate, Agostino, Assereto
Abati, Antonio
10-NA)\u, Ferraro, Giuseppe, ed, Biblioteca comunale ariostea. Mss. (Esteri
I want to make a Custom text facet with openrefine that mark as "true" the names with one comma and "false" all the others, so that I can work with those last (".E., Calvin F." is not a problem, I'll work with that later).
I'm trying using "Custom text facet" and this expression:
if(value.match(/([^,]+),([^,]+)/), "true", "false")
But the result is all false. What's the wrong part?
The expression you are using:
if(value.match(/([^,]+),([^,]+)/), "true", "false")
will always evaluate to false because the output of the 'match' function is either an array, or null. When evaluated by 'if' neither an array nor 'null' evaluate to true.
You can wrap the match function in a 'isNonBlank' or similar to get a boolean true/false, which would then cause the 'if' function to work as you want. However, once you have a boolean true/false result the 'if' becomes redundant as its only function is to turn the boolean true/false into string "true" or "false" - which won't make any difference to the values function of the custom text facet.
So:
isNonBlank(value.match(/([^,]+),([^,]+)/))
should give you the desired result using match
Instead of using 'match' you could use 'split' to split the string into an array using the comma as a split character. If you measure the length of the resulting array, it will give you the number of commas in the string (i.e. number of commas = length-1).
So your custom text facet expression becomes:
value.split(",").length()==2
This will give you true/false
If you want to break down the data based on the number of commas that appear, you could leave off the '==2' to get a facet which just gives you the length of the resulting array.
I would go with lookahead assertion to check if only 1 "," can find from the beginning until the end of line.
^(?=[^\,]+,[^\,]+$).*
https://regex101.com/r/iG4hX6/2

INFORMATICA - Date format conversion

Hello guys i have a date format of 12/05/2015 i.e., dd/mm/yyyy . I need to convert this as 05/12/2015 i.e., mm/dd/yyyy . Can any one give me a solution .
Because function TO_DATE by default expects the date as a char value to be in the form 'MM/DD/YYYY', you need to specify you're handing it in as 'DD/MM/YYYY'. Then you want the final output to be a string (presumably) in format 'MM/DD/YYYY', so for that you need the function TO_CHAR. So you have to jump that hurdle, too. The final statement for your example, then, looks like this:
TO_CHAR(TO_DATE('12/05/2015', 'DD/MM/YYYY'), 'MM/DD/YYYY')
The output will be '05/12/2015'.
Use the function TO_DATE
TO_DATE(Column_name, 'mm/dd/yyyy')
In informatica Help file, There is a chapter called "functions". In that check TO_DATE function.
TO_DATE( string [, format] )
String ---- Must be a string datatype. Passes the values that you want to convert to dates. You can enter any valid transformation expression.
format ---- Enter a valid TO_DATE format string. The format string must match the parts of the string argument. For example, if you pass the string '20150515', you must use the format string 'YYYYMMDD'.
v_PORT(DataType-DateTime)-TO_DATE(TO_CHAR(INPUTPORT),'DD/MM/YYYY')
o_PORT(String)--TO_CHAR(v_PORT,'MM/DD/YYYY')
It will work.
Use the below command, this will give you the value as per you requirement
TO_CHAR(TO_DATE(Column, 'DD/MM/YYYY'), 'MM/DD/YYYY')

Parse ddMMMyy date string with regex in Scala

I wanted to make a regex such that the following date can be matched and its elements passed to another function:
"21Feb14"
Now the problem is the first two digits. The user can write a date in which the 'day' field is one-digit long OR two-digit long:
"21feb14" and "1jan13"
both are valid inputs.
the regex I made looks like this:
val reg = """(\\d)([a-zA-Z][a-zA-Z][a-zA-Z])(\d\d)""".r
It clearly does not take into consideration that the first digit may or may not exist. How do I handle that?
? marks handles that. Like this,
(\d?\d)([a-zA-Z][a-zA-Z][a-zA-Z])(\d\d)
But I suggest you use following regex
(\d?\d)([a-zA-Z]{3})(\d\d)
Or with posix
(\d?\d)([\p{Alpha}]{3})(\d\d)
This one is far more readable and maintainable
val reg = """(\d{1,2})([a-zA-Z]{3})(\d{2})""".r
Explanations here : http://regex101.com/r/uZ9qI5