Is it possible convert text to regex? - regex

As example i have this text
1.2345
12.345
So my input form must following the format above. Is it possible to populate regex dynamically. as example we will use format number 1
User input 12.345 so it will return false, but when user input 5.5555 it will return true, but when user input 1.23 it will return true and the number will become 1.2300
In javascript, i'm doing this
var inputVal = $(this).val();
if (inputVal == "") return;
if (inputVal.indexOf('.') !== -1) {
var inputValSplitdot = inputVal.split(".");
var inputFormatSplitDot = inputFormat.split(".");
if (inputValSplitdot[1].length < inputFormatSplitDot[1].length) {
var compareResult = inputFormatSplitDot[1].length - inputValSplitdot[1].length
var zeroItem = "0".repeat(compareResult);
$(this).val(inputVal + zeroItem);
}
} else {
$(this).val(inputVal + ".").change();
}
How can i achive in flutter/dart ? thanks in advance

This problem can be solved elegantly in Flutter.
First, use RegEx in InputFormatter to make sure users can only enter digits (0-9) and decimal points (.) but not any other characters
inputFormatters: [
// Make sure user can only enter numbers and decimal points
FilteringTextInputFormatter.allow(RegExp(r'[0-9\.]')),
],
Secondly, limit the total input length to 6, so users cannot enter more than that:
maxLength: 6
(Once this is done, Flutter automatically adds a counter, if you don't want the counter, it can be disabled easily by setting counterText: ''.)
Lastly, monitor the input with a TextEditingController, and check if the value entered is valid and within range:
bool isValid(String input) {
if (input.isEmpty) return true; // initial empty string is okay
final number = double.tryParse(input); // try to parse the string
if (number == null) return false; // parse failed: invalid format
if (number >= 100) return false; // range failed: larger than 99.999
return true;
}
Full source code:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("TextField Demo")),
body: Center(
child: SizedBox(
width: 200,
child: VerifiedTextField(),
),
),
);
}
}
class VerifiedTextField extends StatefulWidget {
#override
_VerifiedTextFieldState createState() => _VerifiedTextFieldState();
}
class _VerifiedTextFieldState extends State<VerifiedTextField> {
final _controller = TextEditingController();
bool _valid = true;
#override
void initState() {
_controller.addListener(() {
final valid = isValid(_controller.text);
setState(() => _valid = valid);
});
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return TextField(
controller: _controller,
inputFormatters: [
// Make sure user can only enter numbers and decimal points
FilteringTextInputFormatter.allow(RegExp(r'[0-9\.]')),
],
maxLength: 6,
decoration: InputDecoration(
errorText: _valid ? null : "Incorrect Format",
// counterText: '', // apply this code, if you don't want a counter
),
);
}
bool isValid(String input) {
if (input.isEmpty) return true; // initial empty string is okay
final number = double.tryParse(input); // try to parse the string
if (number == null) return false; // parse failed: invalid format
if (number >= 100) return false; // range failed: larger than 99.999
return true;
}
}
And of course, if you prefer to do it the way you had in JS, you can modify the isValid function accordingly.

If you are working with string then this might be helpful.
There are two ways to construct a regular expression in JavaScript .
Using a regular expression literal, which consists of a pattern enclosed between slashes, as follows.
const reg = /ab+/;
Calling the constructor function of the RegExp object, as follows.
const reg = new RegExp('ab+', flag);

You can try something like this:
First, check if the number provided accomplished the regex expression
bool isMatch(String value) {
var hasMatch = !RegExp("^\d\.\d+").hasMatch(value);
if (hasMatch && value.length < 6) newText(value);
return hasMatch;
}
Secondly, modify the number length if necessary
void newText(String value) {
for (var i = value.length; i < 6; i++) {
value += '0';
}
}

This is how I do it in javascript
// returns true if pattern matches text
function checkPattern(pattern, input) {
return (input.match(pattern)) ? true : false
}
// regex pattern
let pattern = /[0-9]{1}[.][0-9]{4}/g
let pattern2 = /[0-9]{2}[.][0-9]{3}/g
let input = ["1.2345", "12.345", "5.5555", "1.23"]
for (let i in input) {
console.log(`checking first pattern on input: ${input[i]} ${checkPattern(pattern, input[i])}`)
console.log(`checking second pattern on input: ${input[i]} ${checkPattern(pattern2, input[i])}`)
}
the output is
checking first pattern on input: 1.2345 true
checking second pattern on input: 1.2345 false
checking first pattern on input: 12.345 false
checking second pattern on input: 12.345 true
checking first pattern on input: 5.5555 true
checking second pattern on input: 5.5555 false
checking first pattern on input: 1.23 false
checking second pattern on input: 1.23 false

Related

Flutter: Selected value doesn't display in the dropdown

I'm populating cities name from SQLite database and trying to display as a drop down list. I make it work by following a tutorial, but having a small issue. The selected value is not displayed in dropdown, it keep displaying default hint value. However, I was able to assign and retrieve correct selected value.
Here is my code:
cities.dart
class Cities {
int id;
String name;
Cities(this.id, this.name);
Cities.fromMap(Map<String, dynamic> json) {
this.id = json["id"];
this.name = json["name"];
}
Map<String, dynamic> toMap() => {
'id': null,
'name': name,
};
}
Function that retrieve and returns value from db:
Future<List<Cities>> getCitiesList() async {
Database db = await instance.database;
final citiesData = await db.query('cities');
if (citiesData.length == 0) return null;
List<Cities> citiesList = citiesData.map((item) {
return Cities.fromMap(item);
}).toList();
return citiesList;
}
The code which builds drop down, inside Widget build:
//these are defined above in the code
Cities _city;
final databaseHelper = DatabaseHelper.instance;
FutureBuilder<List<Cities>>(
future: databaseHelper.getCitiesList(),
builder: (BuildContext context, AsyncSnapshot<List<Cities>> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return DropdownButton<Cities>(
items: snapshot.data
.map((city) => DropdownMenuItem<Cities>(
child: Text(city.name),
value: city,
))
.toList(),
onChanged: (Cities value) {
setState(() {
_city = value;
});
},
isExpanded: true,
// value: _city, //uncommenting this line breaks the layout
hint: Text('Select City'),
);
},
),
Error in the console:
'package:flutter/src/material/dropdown.dart': Failed assertion: line 620 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not true.
Un-commenting this value: _city, add same error in display (displays error 8 times, instead of dropdown list).
Questions:
How can I fix this issue?
How can I set default value from the list? (which will be selected by default)
You can do it in simple way, just create a simple list of strings and pass that list to dropdown menu.
Here's how:
Update your getCitiesList() function:
Future<List<String>> getCitiesList() async {
Database db = await instance.database;
final citiesData = await db.query(tblCities);
if (citiesData.length == 0) return null;
return citiesData.map((Map<String, dynamic> row) {
return row["name"] as String;
}).toList();
}
Add this inside your form page:
//initialize these at top
List<String> _citiesList = <String>[];
String _city;
void _getCitiesList() async {
final List<String> _list = await databaseHelper.getCitiesList();
setState(() {
_citiesList = _list;
});
}
Call _getCitiesList(); inside initState().
Add this inside your build method:
DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: _city,
items: _citiesList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
_city = newValue;
});
},
)),

Prevent user from entering numbers but keep the alphabetical characters they have already entered

I'm trying to stop user from entering numbers in an input form but keep alphabetical characters. At the moment,as soon as the user enters a number, my code erases everything entered before, e.g. "Ann3" turns to an "".
I don't know how to keep "Ann" when the user accidentally hits "3". This is what I've got so far:
updateName(event) {
var value = event.target.value;
var model = this.state;
if (!value.match("^[a-zA-Z]*$")) {
value = "";
};
this.setState({ [event.target.name]: value })
I wonder if I could use concatenation here, I'm sorry, I'm new to ReactJS and programming in general and don't know where to start.
Rather than setting value to the empty string, you could use .replace to replace all non-alphabetical characters with the empty string (thereby keeping alphabetical characters and their relative positions):
updateName(event) {
const { value, name } = event.target;
this.setState({ [name]: value.replace(/[^a-z]/gi, '') });
}
i did a code sample with react bootstrap but i'm sure it will work for you:
let { FormGroup,ControlLabel,FormControl } = ReactBootstrap;
class Example extends React.Component {
constructor(props, context) {
super(props, context);
this.handleChange = this.handleChange.bind(this);
this.state = {
value: ''
};
}
getValidationState() {
const length = this.state.value.length;
if (length > 3) return 'success';
else if (length > 2) return 'warning';
else if (length > 0) return 'error';
return null;
}
handleChange(e) {
this.setState({value : e.target.value.replace(/[^a-z]/gi, '')})
}
render() {
return (
<form>
<FormGroup
controlId="formBasicText"
validationState={this.getValidationState()}
>
<ControlLabel>keep alphabetical characters</ControlLabel>
<FormControl
type="text"
value={this.state.value}
placeholder="Enter text"
onChange={this.handleChange}
/>
<FormControl.Feedback />
</FormGroup>
</form>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('app')
);
https://codepen.io/ene_salinas/pen/zmMyOb?editors=0010
Happy coding!

Swift: Finding an Object Property via regex

Target: The following function shall iterate over an array of objects and check a specific property of all objects. This property is a string and shall be matched with a user input via regex. If there's a match the object shall be added to an array which will further be passed to another function.
Problem: I don't know how to set up regex in Swift 3. I'm rather new in Swift at all, so an easily understandable solution would be very helpful :)
How it currently looks like:
func searchItems() -> [Item] {
var matches: [Item] = []
if let input = readLine() {
for item in Storage.storage.items { //items is a list of objects
if let query = //regex with query and item.name goes here {
matches.append(item)
}
}
return matches
} else {
print("Please type in what you're looking for.")
return searchItems()
}
}
This is what Item looks like (snippet):
class Item: CustomStringConvertible {
var name: String = ""
var amount: Int = 0
var price: Float = 0.00
var tags: [String] = []
var description: String {
if self.amount > 0 {
return "\(self.name) (\(self.amount) pcs. in storage) - \(price) €"
} else {
return "\(self.name) (SOLD OUT!!!) - \(price) €"
}
}
init(name: String, price: Float, amount: Int = 0) {
self.name = name
self.price = price
self.amount = amount
}
}
extension Item: Equatable {
static func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.name == rhs.name
}
}
Solved. I just edited this post to get a badge :D
For the purpose of letting the answer to be generic and clear, I will assume that the Item model is:
struct Item {
var email = ""
}
Consider that the output should be a filtered array of items that contains items with only valid email.
For such a functionality, you should use NSRegularExpression:
The NSRegularExpression class is used to represent and apply regular
expressions to Unicode strings. An instance of this class is an
immutable representation of a compiled regular expression pattern and
various option flags.
According to the following function:
func isMatches(_ regex: String, _ string: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: regex)
let matches = regex.matches(in: string, range: NSRange(location: 0, length: string.characters.count))
return matches.count != 0
} catch {
print("Something went wrong! Error: \(error.localizedDescription)")
}
return false
}
You can decide if the given string does matches the given regex.
Back to the example, consider that you have the following array of Item Model:
let items = [Item(email: "invalid email"),
Item(email: "email#email.com"),
Item(email: "Hello!"),
Item(email: "example#example.net")]
You can get the filtered array by using filter(_:) method:
Returns an array containing, in order, the elements of the sequence
that satisfy the given predicate.
as follows:
let emailRegex = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let emailItems = items.filter {
isMatches(emailRegex, $0.email)
}
print(emailItems) // [Item(email: "email#email.com"), Item(email: "example#example.net")]
Hope this helped.
You can do the same with filter function
let matches = Storage.storage.items.filter({ $0.yourStringPropertyHere == input })

Regex for javafx spinner control

SpinnerValueFactory svf = new SpinnerValueFactory.DoubleSpinnerValueFactory(-500,500,1,0.5);
spiKolicina.setValueFactory(svf);
spiKolicina.setEditable(true);
UnaryOperator<TextFormatter.Change> filter = new UnaryOperator<TextFormatter.Change>() {
#Override
public TextFormatter.Change apply(TextFormatter.Change t) {
if (t.isReplaced())
if(t.getText().matches("[^0-9]"))
t.setText(t.getControlText().substring(t.getRangeStart(), t.getRangeEnd()));
if (t.isAdded()) {
if (t.getControlText().contains(".")) {
if (t.getText().matches("[^0-9]")) {
t.setText("");
}
}
else if (t.getText().matches("[^0-9.]")) {
t.setText("");
}
}
return t;
}
};
spiKolicina.getEditor().setTextFormatter(new TextFormatter<>(filter));
How to alter regex expression to allow me to enter negative double number in spinner textfield?
Also when the spinner textfield is empty and you press the up or down btn it gives nullPointException, i would like it to go to some default value
I usually find it easier to check the resulting text from a change; return the change "as-is" if it is ok, and return null otherwise. Here you want the resulting text to be an optional negative sign, zero or more digits, an options decimal separator, and zero or more digits. (Note this allows any valid floating point number, or an empty string, or a negative sign or digital separator on its own.)
So for the filter:
UnaryOperator<TextFormatter.Change> filter = new UnaryOperator<TextFormatter.Change>() {
#Override
public TextFormatter.Change apply(TextFormatter.Change t) {
String newText = t.getControlNewText() ;
if (newText.matches("-?[0-9]*\\.?[0-9]*")) {
return t ;
}
return null ;
}
};
You can also define a converter, which you can use with both the spinner itself and the text field which is the editor for the spinner. This just needs to parse the string as a double, but should handle the special cases of -, ., and -.. So:
StringConverter<Double> converter = new StringConverter<Double>() {
#Override
public String toString(Double object) {
return object.toString() ;
}
#Override
public Double fromString(String string) {
if (string.isEmpty() || ".".equals(string) || "-".equals(string) || "-.".equals(string)) {
return 0.0 ;
} else {
return new Double(string);
}
}
};
then do
svf.setConverter(converter);
spinner.getEditor().setTextFormatter(new TextFormatter<>(converter, 0.0, filter));
This converter will properly handle interpreting empty strings, etc, as 0.0, and so will avoid the exception when you try to increment or decrement when the editor is in that state.
SSCCE:
import java.util.function.UnaryOperator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class SpinnerTest extends Application {
#Override
public void start(Stage primaryStage) {
SpinnerValueFactory<Double> svf = new SpinnerValueFactory.DoubleSpinnerValueFactory(-500,500,1,0.5);
Spinner<Double> spinner = new Spinner<>();
spinner.setValueFactory(svf);
spinner.setEditable(true);
UnaryOperator<TextFormatter.Change> filter = new UnaryOperator<TextFormatter.Change>() {
#Override
public TextFormatter.Change apply(TextFormatter.Change t) {
String newText = t.getControlNewText() ;
if (newText.matches("-?[0-9]*\\.?[0-9]*")) {
return t ;
}
return null ;
}
};
StringConverter<Double> converter = new StringConverter<Double>() {
#Override
public String toString(Double object) {
return object.toString() ;
}
#Override
public Double fromString(String string) {
if (string.isEmpty() || ".".equals(string) || "-".equals(string) || "-.".equals(string)) {
return 0.0 ;
} else {
return new Double(string);
}
}
};
svf.setConverter(converter);
spinner.getEditor().setTextFormatter(new TextFormatter<>(converter, 0.0, filter));
StackPane root = new StackPane(spinner);
primaryStage.setScene(new Scene(root, 180, 80));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

How to Filter special characters or anything that doesn't matches the search String in MVC

i want to filter the search string entered in a way that it doesn't accept anything other than the matched string for Searching.
Here is my Controller code:
public ActionResult SearchProduct(string SearchString)
{
FlipcartDBContextEntities db = new FlipcartDBContextEntities();
if(ModelState.IsValid)
{
// if ModelState is true
string noResult = "Search Result Not Found";
var products = from p in db.Products select p;
if (!String.IsNullOrEmpty((SearchString).Trim()))
{
products = products.Where(s => s.ProductName.Contains(SearchString));
return View(products.ToList());
}
else
{
ViewBag.Message = noResult;
return View(new List<Product>());
}
}
else
{
ModelState.AddModelError("", "Search not successful");
}
return View();
}
"Search Result Not Found" is displaying only for null entry..but i want it to display for any other characters that doesn't matches the search string.
How do i do that?
Try this:
if(ModelState.IsValid)
{
// if ModelState is true
string noResult = "Search Result Not Found";
//ternary expression to return a new list if Search string is null or empty
var products = string.IsNullOrEmpty(SearchString.Trim())
? new List<Product>()
: db.Products
.Where(s => s.ProductName.Contains(SearchString));
//set viewbag message if list is empty
if(!products.Any())
{
ViewBag.Message = noResult;
}
return View(products.ToList());
}
else
{
ModelState.AddModelError("", "Search not successful");
}