133

In a Flutter application, I need to check if a string matches a specific RegEx. However, the RegEx I copied from the JavaScript version of the app always returns false in the Flutter app. I verified on regexr that the RegEx is valid, and this very RegEx is already being used in the JavaScript application, so it should be correct.

Any help is appreciated!

RegEx : /^WS{1,2}:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:56789/i

Test Code :

RegExp regExp = new RegExp(
  r"/^WS{1,2}:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:56789/i",
  caseSensitive: false,
  multiLine: false,
);
print("allMatches : "+regExp.allMatches("WS://127.0.0.1:56789").toString());
print("firstMatch : "+regExp.firstMatch("WS://127.0.0.1:56789").toString());
print("hasMatch : "+regExp.hasMatch("WS://127.0.0.1:56789").toString());
print("stringMatch : "+regExp.stringMatch("WS://127.0.0.1:56789").toString());

Output :

allMatches : ()
firstMatch : null
hasMatch : false
stringMatch : null
Nato Boram
  • 4,083
  • 6
  • 28
  • 58

2 Answers2

162

This is a more general answer for future viewers.

Regex in Dart works much like other languages. You use the RegExp class to define a matching pattern. Then use hasMatch() to test the pattern on a string.

Examples

Alphanumeric

final alphanumeric = RegExp(r'^[a-zA-Z0-9]+$');
alphanumeric.hasMatch('abc123');  // true
alphanumeric.hasMatch('abc123%'); // false

Hex colors

RegExp hexColor = RegExp(r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$');
hexColor.hasMatch('#3b5');     // true
hexColor.hasMatch('#FF7723');  // true
hexColor.hasMatch('#000000z'); // false

Extracting text

final myString = '25F8..25FF    ; Common # Sm   [8] UPPER LEFT TRIANGLE';

// find a variable length hex value at the beginning of the line
final regexp = RegExp(r'^[0-9a-fA-F]+'); 

// find the first match though you could also do `allMatches`
final match = regexp.firstMatch(myString);

// group(0) is the full matched text
// if your regex had groups (using parentheses) then you could get the 
// text from them by using group(1), group(2), etc.
final matchedText = match?.group(0);  // 25F8

There are some more examples here.

See also:

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 1
    @LeoK, It does work but it isn't very useful in this case. What you get is a list with two items: everything before `25F8` at the start of the string (which is an empty string) and everything after it. – Suragch Jun 15 '21 at 03:10
  • The medium article in "see also" section is hidden behind a paywall https://medium.com/flutter-community/extracting-text-from-a-string-with-regex-groups-in-dart-b6be604c8a69 – Kevo1ution Apr 13 '23 at 19:13
  • @Kevo1ution, Thanks for telling me. I've updated the link with a non-paywalled version. – Suragch Apr 15 '23 at 08:04
107

I think you tried to include options in the raw expression string while you already have it as parameters to RegEx ( /i for case insensitivity is declared as caseSensitive: false).

// Removed /i at the end
// Removed / in front - Thanks to Günter for warning
RegExp regExp = new RegExp(
  r"^WS{1,2}:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:56789",
  caseSensitive: false,
  multiLine: false,
);
print("allMatches : "+regExp.allMatches("WS://127.0.0.1:56789").toString());
print("firstMatch : "+regExp.firstMatch("WS://127.0.0.1:56789").toString());
print("hasMatch : "+regExp.hasMatch("WS://127.0.0.1:56789").toString());
print("stringMatch : "+regExp.stringMatch("WS://127.0.0.1:56789").toString());

Gives:

allMatches : (Instance of '_MatchImplementation')
firstMatch : Instance of '_MatchImplementation'
hasMatch : true
stringMatch : WS://127.0.0.1:56789
Cetin Basoz
  • 22,495
  • 3
  • 31
  • 39
  • 6
    The `/` at the beginning also doesn't work in Dart AFAIK – Günter Zöchbauer Apr 10 '18 at 16:02
  • In DartPad it works for me. Ooops. You are right, I removed that too in DartPad. Thanks. – Cetin Basoz Apr 10 '18 at 16:15
  • 3
    Thanks! It is a real shame that the [documentation](https://api.dartlang.org/stable/1.24.3/dart-core/RegExp-class.html) lacks this basic but crucial information. I can only hope that Dart will become as documented as Go one day. – Nato Boram Apr 10 '18 at 17:33
  • 2
    @NatoBoram, I second on that (and I really wish Go was chosen for Flutter:) – Cetin Basoz Apr 11 '18 at 10:25
  • 1
    I can see that the `RegExp` constructor doesn't give a code example, you have to look at the class documentation to see that. We might want to have both, to easily catch users that are used to JavaScript regexp syntax. – lrn Apr 11 '18 at 12:39
  • 1
    @lrn, I thought I also looked in class documentation and it is not there. If I am mistaken, can you give the link? Dart documentation feels like an automated doc created from class members with no additional explanations and\or examples (there are examples but few, it is more like a try and see yourself). – Cetin Basoz Apr 11 '18 at 13:07
  • 1
    The [RegExp class](https://api.dartlang.org/stable/1.24.3/dart-core/RegExp-class.html) has a simple example saying `new RegExp(r"(\w+)")`. It's not a lot of example, but it does show that there are no `/`s in the string. Still, the constructor definitely needs more txt to say what fx `caseInsensitive` means. – lrn Apr 12 '18 at 12:47
  • 1
    @lrn, I see, that was all I saw too. Anyway, I love Flutter thus have to love Dart too (wishing it used Go instead aside). – Cetin Basoz Apr 12 '18 at 13:05
  • Could drop the toString() ```+regExp.stringMatch("WS://127.0.0.1:56789").toString()``` – Ride Sun Dec 02 '19 at 23:28