Is it possible convert text to regex?

262

Solution 1

This problem can be solved elegantly in Flutter.

demo gif

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.

Solution 2

If you are working with string then this might be helpful.

There are two ways to construct a regular expression in JavaScript .

  1. Using a regular expression literal, which consists of a pattern enclosed between slashes, as follows. const reg = /ab+/;
  2. Calling the constructor function of the RegExp object, as follows. const reg = new RegExp('ab+', flag);

Solution 3

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';
        }
      }
Share:
262
Boby
Author by

Boby

Always Curious about programming http://tukangaplikasi.com/

Updated on December 31, 2022

Comments

  • Boby
    Boby over 1 year

    As example i have this text

    1. 1.2345

    2. 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

  • Marco Sacchi
    Marco Sacchi over 2 years
    According to the user's requests, I think you should integrate the regex with a quantifier in order to limit the digits before the decimal point. Limiting the maximum length to 6 is not enough.
  • WSBT
    WSBT over 2 years
    @MarcoSacchi There's no need to use RegEx for that, the range check already covers that case and the code is a lot easier to read. Once users enter more than 2 digits before the decimal, it will fail at "number >= 100".
  • Marco Sacchi
    Marco Sacchi over 2 years
    I was referring to this sentence in the question "User input 12.345 so it will return false", so for format number 1 the user expects a single digit before the decimal point. You could specify the two checks necessary to use the two required formats: number >= 100 (as you wrote), and number >= 10.
  • WSBT
    WSBT over 2 years
    @MarcoSacchi Ahhh, I just read the question again, and you are absolutely correct. It seems the OP was asking for 2 different (and competing) situations.