Flutter正则表达式构建插件regex_builder的使用

Flutter正则表达式构建插件regex_builder的使用

特性

RegexBuilder 遵循 RegExp 的规范,因此所有方法和属性都可以使用。

示例:查找HTML标签

以下示例展示了如何在字符串中找到所有的HTML标签。

import 'package:regex_builder/regex_builder.dart';

void main() {
  final regex = RegexBuilder([
    Group([
      Literal('<'),                                   // &
      Group([
          CharacterSet.letter(LetterCase.lower),      // [a-z]
          ZeroOrMore(
            CharacterSet([
              CharacterSet.letter(),                  // [a-zA-Z]
              CharacterSet.number(0, 9),              // [0-9]
            ]),                                       // [a-zA-Z0-9]
          ),                                          // [a-zA-Z0-9]*
        ],                                            // [a-z][a-zA-Z0-9]*
        behavior: GroupBehavior.capture('tag'),
      ),                                              // (?<tag>[a-z][a-zA-Z0-9]*)?
      Literal('>'),                                   // >
    ]),                                               // <(?<tag>[a-z][a-zA-Z0-9]*)>
    Group(
      OneOrMore(AnyCharacter(), greedy: false),       // .+?
      behavior: GroupBehavior.capture(),
    ),                                                // (.+?)
    Literal('</'),                                    // </
    Reference('tag'),                                 // \k<tag>
    Literal('>'),                                     // >
  ]);                                                 // <(?<tag>[a-z][a-zA-Z0-9]*)>(.+?)</\k<tag>>

  final html = '<h1>Hello, world!</h1><a>Google</a>';

  for (final match in regex.allMatches(html)) {
    print('All Match: ${match.group(0)}');
    print('Tag: ${match.group(1)}');
    print('Content: ${match.group(2)}');
  }
}

输出结果

All Match: <h1>Hello, world!</h1>
Tag: h1
Content: Hello, world!
All Match: <a>Google</a>
Tag: a
Content: Google

组件

一个 RegexBuilder 由一组组件组成。可用的组件包括:

  • 字面量 (Literal)
  • 通配符 (AnyCharacter)
  • 选择器 (ChoiceOf)
  • 量词 (ZeroOrMore, OneOrMore, Optionally, Repeat)
  • 字符集 (CharacterSet)
  • (Group)
  • 锚点 (Anchor)

字面量

字面量是一个必须精确匹配的字符串。

Literal('abc'); // 这表示模式 'abc'

通配符

通配符是一个匹配任何字符的字符。

AnyCharacter(); // 这表示模式 '.'

注意:要匹配一个字面量的点,应使用 Literal('.')

选择器

选择器是一组组件,其中任何一个都可能匹配。

ChoiceOf([
  Literal('cat'),
  Literal('dog'),
]); // 这表示模式 'cat|dog'

量词

量词用于指定某个组件应该匹配多少次。

ZeroOrMore

匹配零次或一次。

ZeroOrMore(Literal('a')); // 这表示模式 'a*'
OneOrMore

匹配一次或多次。

OneOrMore(Literal('a')); // 这表示模式 'a+'
Optionally

匹配零次或一次。

Optionally(Literal('a')); // 这表示模式 'a?'
Repeat

匹配特定次数。

Repeat(
  Literal('a'),
  range: RepeatRange.atLeast(3),
); // 这表示模式 'a{3,}'

Repeat(
  Literal('a'),
  range: RepeatRange.atMost(3),
); // 这表示模式 'a{0,3}'

Repeat(
  Literal('a'),
  range: RepeatRange.exactly(3),
); // 这表示模式 'a{3}'

Repeat(
  Literal('a'),
  range: RepeatRange.between(3, 5),
); // 这表示模式 'a{3,5}'

字符集

字符集表示一组字符中的任意一个。

CharacterSet([
  CharacterSet.letter(),
  CharacterSet.number(0, 9),
]); // 这表示模式 '[a-zA-Z0-9]'

组是一组必须一起匹配的组件。默认情况下,组是非捕获的。

Group([
  Literal('a'),
  Literal('b'),
]); // 这表示模式 '(?:ab)'
捕获组

捕获组是一组必须一起匹配且会被捕获的组件。

Group([
  Literal('a'),
  Literal('b'),
], behavior: GroupBehavior.capture()); // 这表示模式 '(ab)'

Group([
  Literal('a'),
  Literal('b'),
], behavior: GroupBehavior.capture('group_name')); // 这表示模式 '(?<group_name>ab)'

锚点

锚点是一个匹配字符串开始或结束位置的组件。

Anchor.startOfLine; // 这表示模式 '^'
Anchor.endOfLine; // 这表示模式 '$'

示例代码

import 'package:regex_builder/regex_builder.dart';

void main() {
  final regex = RegexBuilder([
    Group([
      Literal('<'),                                   // &
      Group([
          CharacterSet.letter(LetterCase.lower),      // [a-z]
          ZeroOrMore(
            CharacterSet([
              CharacterSet.letter(),                  // [a-zA-Z]
              CharacterSet.number(0, 9),              // [0-9]
            ]),                                       // [a-zA-Z0-9]
          ),                                          // [a-zA-Z0-9]*
        ],                                            // [a-z][a-zA-Z0-9]*
        behavior: GroupBehavior.capture('tag'),
      ),                                              // (?<tag>[a-z][a-zA-Z0-9]*)?
      Literal('>'),                                   // >
    ]),                                               // <(?<tag>[a-z][a-zA-Z0-9]*)>
    Group(
      OneOrMore(AnyCharacter(), greedy: false),       // .+?
      behavior: GroupBehavior.capture(),
    ),                                                // (.+?)
    Literal('</'),                                    // </
    Reference('tag'),                                 // \k<tag>
    Literal('>'),                                     // >
  ]);                                                 // <(?<tag>[a-z][a-zA-Z0-9]*)>(.+?)</\k<tag>>

  final html = '<h1>Hello, world!</h1><a>Google</a>';

  for (final match in regex.allMatches(html)) {
    print('All Match: ${match.group(0)}');
    print('Tag: ${match.group(1)}');
    print('Content: ${match.group(2)}');
  }
}

更多关于Flutter正则表达式构建插件regex_builder的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter正则表达式构建插件regex_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用regex_builder插件来构建和使用正则表达式的示例代码。

首先,你需要在pubspec.yaml文件中添加regex_builder依赖项:

dependencies:
  flutter:
    sdk: flutter
  regex_builder: ^latest_version  # 请将latest_version替换为当前最新版本号

然后,运行flutter pub get来安装依赖项。

接下来,我们来看一个完整的示例,展示如何使用regex_builder插件来构建一个正则表达式,并在Flutter应用中应用它。

import 'package:flutter/material.dart';
import 'package:regex_builder/regex_builder.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _controller = TextEditingController();
  String _result = '';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Regex Builder Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              TextField(
                controller: _controller,
                decoration: InputDecoration(
                  labelText: 'Enter text to match',
                ),
              ),
              SizedBox(height: 16),
              RegexBuilder(
                onRegexChanged: (regex) {
                  setState(() {
                    _result = _matchTextWithRegex(_controller.text, regex);
                  });
                },
              ),
              SizedBox(height: 16),
              Text(
                'Match Result: $_result',
                style: TextStyle(fontSize: 18),
              ),
            ],
          ),
        ),
      ),
    );
  }

  String _matchTextWithRegex(String text, RegExp regex) {
    Iterable<RegExpMatch> matches = regex.allMatches(text);
    if (matches.isEmpty) {
      return 'No match found';
    } else {
      return matches.map((match) => match.group(0)).join(', ');
    }
  }
}

class RegexBuilder extends StatefulWidget {
  final ValueChanged<RegExp> onRegexChanged;

  RegexBuilder({required this.onRegexChanged});

  @override
  _RegexBuilderState createState() => _RegexBuilderState();
}

class _RegexBuilderState extends State<RegexBuilder> {
  final _regexController = TextEditingController();

  @override
  void dispose() {
    _regexController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        TextField(
          controller: _regexController,
          decoration: InputDecoration(
            labelText: 'Enter regex pattern',
          ),
          onChanged: (value) {
            try {
              RegExp regex = RegExp(value);
              widget.onRegexChanged(regex);
            } catch (e) {
              // Handle invalid regex pattern here, e.g., show an error message
            }
          },
        ),
        SizedBox(height: 8),
        // You can add more UI elements here to help build the regex pattern,
        // such as buttons for adding common regex components (e.g., *, ?, +, {}, [], (), |, ., ^, $, \d, \w, etc.).
        // For simplicity, this example only includes a basic text field.
      ],
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,包含一个文本输入字段用于输入要匹配的文本,一个RegexBuilder组件用于输入正则表达式,以及一个显示匹配结果的文本字段。

RegexBuilder组件是一个自定义的StatefulWidget,它包含一个文本字段用于输入正则表达式。每当文本字段的内容发生变化时,它都会尝试创建一个RegExp对象,并通过onRegexChanged回调将其传递给父组件。如果正则表达式无效,你可以在onChanged回调中添加错误处理逻辑。

请注意,这个示例中的RegexBuilder组件仅包含一个基本的文本字段。在实际应用中,你可能需要添加更多的UI元素来方便地构建复杂的正则表达式,例如按钮用于插入常见的正则表达式组件(如量词、字符类、分组等)。

希望这个示例能帮你入门如何在Flutter项目中使用regex_builder插件!

回到顶部