Regex Validation for userInput in React - javascript

I am trying to implement a search using regex . To validate if the entered value is a valid regex in the search box I am using the source code from a library regex-validate (REGEX VALIDATION LIBRARY - regex-regex)
If the entered value is a valid regex then I am Parsing it to a regular expression using the source code from this library Regex-Parse) (PARSING LIBRARY - Regex Parser) to filter/search using the parsed regex.Here is a code snippet for the same
import { useState } from "react";
import "./styles.css";
import { re, RegexParser } from "./regexValidation";
export default function App() {
const [val, setVal] = useState("");
const [validRegex, setValidRegex] = useState(false);
const validateRegex = (val: string) => {
setVal(val);
if (val === "") {
setValidRegex(false);
return;
}
// to check if the entered value(val) is a valied regex in string
if (re.test(val)) {
setValidRegex(false);
// parsing the entered value(val) to a regularexpression
const convertToRegex = RegexParser(val);
//filtering logic to filter based on convertToRegex variable
} else {
setValidRegex(true);
}
};
const handleChange = (e: any) => {
validateRegex(e.target.value);
};
return (
<div className="App">
<input value={val} onChange={handleChange}></input>
<h1>{validRegex ? "inValidRegex" : "ValidRegex"}</h1>
</div>
);
}
CodeSandBox link for the regex search RegexValidationSearch
I am facing an issue when the user enters '/?/' or '/*/' the re.test(val) returns true thereby implying that it is a valid regex but when it is trying to get parsed that is this line of code const convertToRegex = RegexParser(val) it throws the following errorRegexError
Is there any way to fix this such that this line of code re.test(val) returns false when the user enters any invalid regular expression there by implying that it is an invalid regex(in string format) and hence there is no need to parse it to a regular expression

This looks like it might be an incompatibility between the two libraries you are using (ie, they have different ideas of what valid Regex is).
Easiest way to fix this (and honestly the safest too, since you're dealing with user input) is to wrap your entire parsing logic with a try/catch like this:
// to check if the entered value(val) is a valied regex in string
if (re.test(val)) {
let convertToRegex;
try {
convertToRegex = RegexParser(val);
setValidRegex(true); // only set this AFTER a successful parse.
// also note I've swapped the true / false value here.
} catch (e) {
setValidRegex(false);
}
if (convertToRegex) {
// TODO: implement filtering logic based on convertToRegex variable
}
} else {
// NOTE: it didn't parse correctly, shouldn't this be false?
setValidRegex(false); // I've changed it for you
}
Also I think(?) you've made a couple errors in how you're handling setValidRegex which I've corrected in code. Don't be optimistic and say the user input is valid regex when you haven't actually confirmed (by creating a RegexParser) that it is!
With this approach there's an argument for deleting the re.test(val) and the other library entirely since you can get what you want by simply try/catch-ing. Up to you to decide if this is a decent choice for your codebase.

Related

How to format the TextInput component value in react native?

I use this function to format every number input I have :
export const parseToNumber = (value: string) => {
const numberRegex = /^[0-9\b]+$/;
if (numberRegex.test(value)) {
return value;
} else {
return value.replace(/\D/g, "");
}
};
And I use it with another function to have a an empty space between every 4 characters like this :
onChangeText={(e) => {
setFieldValue(
"phone",
parseToNumber(e).replace(/(.{4})/g, "$1 ")
);
}}
The problem is the Backspace won't work because of the parseToNumber . How can I exclude the functions when the user presses the Backspace and use the simple way like this setFieldValue("phone", (e)); so the backspace works ?
Or is there another way to fix the Backspace disabled problem with these functions in place possibly modify the parseToNumber function ?
If Problem is parseToNumber, you can make sure only take numbers by opening numbers only keyboard by passing prop
keyboardType = 'numeric'
or to simplify the use and support multiple spacing for input you can use this library - react-native-mask-input, its js only library so you can also just copy the specific implementation on need to use basis.

Escaping square brackets with node expressionparser

I am using node expressionparser in combination with jsonpath-plus library to parse json paths and read the data out of a json object based on the term returned. Here is what my parser code looks like:
export function initialiseParser(workerObject: WorkerObjectType): ExpressionParser {
return init(formula, (term: string) => {
if (term === '$NULL') {
return '$NULL';
} else if (term.startsWith('$VALUE:')) {
const [, key] = term.split('$VALUE:');
return getJsonData({ path: key, json: workerObject }) ?? '$NULL';
} else {
return '$NULL';
}
});
}
I am trying to parse the below expression:
$VALUE:Worker_Data.Employment_Data.Worker_Job_Data[?(#.attributes['wd:Primary_Job'] === '1')].Position_Data.Business_Site_Summary_Data.Name
When running this through the parser, I can see the term evaluates to .Position_Data.Business_Site_Summary_Data.Name. The result I would like to achieve is to get out the full expression: Worker_Data.Employment_Data.Worker_Job_Data[?(#.attributes['wd:Primary_Job'] === '1')].Position_Data.Business_Site_Summary_Data.Name.
My gut feeling is that the formula language is recognizing the '[]' and parses it at something else but looking through the docs I am unclear as to what.
I wonder is someone could shed some light on this for me? If formula uses [] for something else, how can I escape the character when using it in the expression? Also open to other solutions. Please let me know if more details are required.

How to format number correctly in a calculator app (React)?

This is my first time posting in SO, and I need help formatting numbers correctly in a calculator app that I've made using ReactJS.
Here is the link on StackBlitz.
Now, I want to achieve the formatting effect after numbers are pressed and shown in the display and arithmetic signs are added, especially when multiple arithmetics are used.
To illustrate my point, below is a sample of the current display:
123456 + 7890123 * 11111
And what I want to achieve is this:
123,456 + 7,890,123 * 11,111
I could only do this when displaying the result using the toLocaleString() function. Even then, if I pressed number/numbers and then clicking the result button twice, it will be crashed (as the display contains a comma, and the evaluation function will not process it properly).
Hopefully, someone can point me out in the right direction. Thanks.
Quick Fix
You can remove ',' before evaluating the result.
Change line 65 of Input.js to
setDisplay(evaluate(display.replace(/,/g, '')).toLocaleString());
Better Solution
Keep separate variables for Internal logical state and External Display state, where the former is valid for code and the latter is its visual representation.
You can achieve this by useEffect like this
/* --- Display.js --- */
const Display = ({ display }) => {
const [printValue, setPrintValue] = useState('')
useEffect(() => {
setPrintValue(`${display}`.replace(/[0-9]+/g, num => (+num).toLocaleString()))
}, [display])
return (
<StyledDisplay>
{' '}
<span>{printValue}</span>{' '}
</StyledDisplay>
);
};
Also, in Input.js, update line 65 in handleResult to
setDisplay(evaluate(display));
For this kind of situations, I like to use regex. Here what you can do is to use a regex that matches 3 digits and add the comma as wanted. To simplify the regex I usually reverse the string:
const original = "123456 / 98765 * 22222"
function format(str) {
const reversed = str.split('').reverse().join('')
const formatted = reversed.replace(/(\d{3})(?=\d)/gm, `$1,`)
return formatted.split('').reverse().join('')
}
console.log('original string : ', original)
console.log('result string : ',format(original))
You can use this function in your Display component, just before injecting the display prop like this
function format(str){
const reversed = str.split('').reverse().join('')
const formatted = reversed.replace(/(\d{3})(?=\d)/gm, `$1,`)
return formatted.split('').reverse().join('')
}
const Display = ({ display }) => {
return (
<StyledDisplay>
{' '}
<span>{format(display)}</span>{' '}
</StyledDisplay>
);
};

Translate Special Characters with npm latinize is not working dynamically

I am using latinize to translate german language's special characters to English, they module work only when I pass string within single or double quotes, but not when I pass by storing them inside a variable.
import latinize from 'latinize';
ANd inside render, I console this and it works fine,
console.log('render', latinize('VfL Osnabrück'))
also when i pass my
let tag_name = 'VfL Osnabrück';
console.log('render', latinize('VfL Osnabrück'))
it will again works fine, but did not work fine when I get tag_name from my api. And complete code is below
let tag_parsing = sub_category_id.split('%20');
let tag_string = '';
for (let i = 0; i < tag_parsing.length; i++) {
tag_parsing[i];
// tag_parsing[0] == Vlf
// tag_parsing[1] == Osnabrück
console.log('latinized text', tag_parsing[i]);
tag_string += ' ' + tag_parsing[i]
}
OUTPUT
output of latinized text ==> Osnabr%C3%BCck
output of latinized text inside quotes ==> Osnabruck
I also try with .toString() but did not work
I think there may be something off with how you are attempting to process the query string from the URL.
Here's a snippet of the logic I used to process your query string in a forked codesandbox. I used a functional component for ease, but the same logic can be used in a class-based component.
// get the search string
const { search } = useLocation();
const [latinizedValue, setLatinizedValue] = React.useState("");
React.useEffect(() => {
console.log({ search });
// create search params object
const newParams = new URLSearchParams(search);
const key = newParams.get("key");
const value = newParams.get("value")?.trim();
console.log("Param", key, `"${value}"`);
console.log("latinize param:", `"${latinize(value)}"`);
setLatinizedValue(latinize(value));
}, [search]);
Demo
The font-family that i was using was not contains special german characters, and finally I changed the font-family that supports german special characters, and everything goes smooth and latinize also works fine.

Validating UK PostCode with JavaScript Reg for Angular5 app

I am working on Angular 5 Reactive Form validation and trying to validate UK PostCode using custom validation function which is working and testing apart from in case provide extra letter or numeric value at end of postcode 2nd part, it validate true, for example NW10 5NW is correct but if I type anything like NW10 5NWRRRRRRRRRRRRRRRR is also return true which is not correct.
I have tried following regular experssion on https://regexr.com/ and it return correct response, not sure why in javaScript not behaving same way???
function postCodeValidator(control: FormControl)
{
let givenPostCode = control.value;
let UKPostCodePattern = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\s?[0-9][A-Za-z]{2})/;
var isUKPostCodeValid = UKPostCodePattern.test(givenPostCode);
console.log("postcode validity ",isUKPostCodeValid, " for ", givenPostCode);
if(!isUKPostCodeValid)
{
return {
postCode:{
required:"UK Valid PostCode",
provided: givenPostCode
}
}
}
return null;
}
Try using following regex
^(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\s?[0-9][A-Za-z]{2}))$
https://regexr.com/3pp3r

Categories