搜尋套件、儲存庫與 APP 分類

套件詳情v2.4.0

text_parser

一個用於根據多個正則表達式模式靈活解析文字為易於處理格式的 Dart 套件。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
1380
喜歡數
8
Pub 分數
160

安裝套件

flutter pub add text_parser

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

一個 Dart 套件,旨在透過應用多個正則表達式模式來靈活解析文字,將複雜文字轉換為結構化、易於處理的格式。它讓開發者能夠定義自訂解析規則,並有效提取有意義的資料。非常適合處理具有統一模式的日誌、設定檔或使用者輸入。此套件支援所有主要平台,確保跨平台相容性。其輕量級設計與明確的 API,使其適用於簡單及進階的文字操作任務。

適用情境

  • 解析日誌檔案
  • 從用戶輸入中提取結構化數據
  • 處理配置字串
  • 處理動態文字範本
  • 將原始文字轉換為類似 JSON 的結構

主要特色

  • 支援多個正則表達式模式
  • 靈活且可擴展的解析邏輯
  • 跨平台相容性
  • 用於定義規則的簡單 API
  • 高效的文字轉換
  • 內建錯誤處理

適合對象

  • 使用結構化文字的開發者
  • 需要動態文字處理的應用程式
  • 用於分析或從文字中提取資料的工具
  • 跨平台應用程式
  • 需要自定解析工作流程的專案

使用建議

  • 需要了解正則表達式
  • 效能可能隨著複雜模式而異
  • 未針對非常大的文字檔案進行優化
  • 有限的內建格式化選項
  • 依賴於正確的模式定義以獲得準確的結果

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

Pub Version Dart CI codecov

A Dart package for parsing text flexibly according to preset or custom regular expression patterns.

Usage

Using the preset matchers (URL / email address / phone number)

The package has the following preset matchers.

Below is an example of using three of the preset matchers except for UrlLikeMatcher.

import 'package:text_parser/text_parser.dart';

void main() {
  const text = 'abc https://example.com/sample.jpg. def\n'
      'john.doe@example.com +1-012-3456-7890';

  final parser = TextParser(
    matchers: const [
      EmailMatcher(),
      UrlMatcher(),
      TelMatcher(),
    ],
  );
  final elements = parser.parseSync(text);
  elements.forEach(print);
}

Output:

TextElement(matcherType: TextMatcher, matcherIndex null, offset: 0, text: abc , groups: [])
TextElement(matcherType: UrlMatcher, matcherIndex 1, offset: 4, text: https://example.com/sample.jpg, groups: [])
TextElement(matcherType: TextMatcher, matcherIndex null, offset: 34, text: . def\n, groups: [])
TextElement(matcherType: EmailMatcher, matcherIndex 0, offset: 40, text: john.doe@example.com, groups: [])
TextElement(matcherType: TextMatcher, matcherIndex null, offset: 60, text:  , groups: [])
TextElement(matcherType: TelMatcher, matcherIndex 2, offset: 61, text: +1-012-3456-7890, groups: [])

The regular expression pattern of each of them is not very strict. If it does not meet your use case, overwrite the pattern by yourself to make it stricter.

parse() vs parseSync()

parseSync() literally executes parsing synchronously. If you want to prevent an execution from blocking the UI in Flutter or pauses other tasks in pure Dart, use parse() instead.

  • useIsolate: false
    • Parsing is scheduled as a microtask.
  • useIsolate: true (default)
    • Parsing is executed in an isolate.
    • On Flutter Web, this is treated the same as useIsolate: false since dart:isolate is not supported on the platform.
UrlMatcher vs UrlLikeMatcher

UrlMatcher does not match URLs not starting with "http" (e.g. example.com, //example.com, etc). If you want them to be matched too, use UrlLikeMatcher instead.

matcherType and matcherIndex

matcherType contained in a TextElement object is the type of the matcher that was used to extract the element. matcherIndex is the index of the matcher in the matcher list passed to the matchers argument of TextParser.

Extracting only matching text elements

By default, the result of parse() or parseSync() contains all elements including the ones that have TextMatcher as matcherType, which are elements of a string that did not match any match pattern. If you want to exclude them, pass onlyMatches: true when calling parse() or parseSync().

final elements = parser.parseSync(text, onlyMatches: true);
elements.forEach(print);

Output:

TextElement(matcherType: UrlMatcher, matcherIndex 1, offset: 4, text: https://example.com/sample.jpg, groups: [])
TextElement(matcherType: EmailMatcher, matcherIndex 0, offset: 40, text: foo@example.com, groups: [])
TextElement(matcherType: TelMatcher, matcherIndex 2, offset: 56, text: +1-012-3456-7890, groups: [])
Extracting text elements of a particular matcher type
final telElements = elements.whereMatcherType<TelMatcher>().toList();

Or use a classic way:

final telElements = elements.map((elm) => elm.matcherType == TelMatcher).toList();
Conflict between matchers

If multiple matchers match the string at the same position in text, the first one in those matchers takes precedence.

final parser = TextParser(matchers: const[UrlLikeMatcher(), EmailMatcher()]);
final elements = parser.parseSync('foo.bar@example.com');

In this example, UrlLikeMatcher matches foo.bar and EmailMatcher matches foo.bar@example.com, but UrlLikeMatcher is used because it is written before EmailMatcher in the matchers list.

Overwriting the pattern of a preset matcher

If you want to parse a sequence of eleven numbers after "tel:" as a phone number:

TelMatcher(r'(?<=tel:)\d{11}')
Using a custom pattern

You can create a matcher with a custom pattern either with PatternMatcher or by extending TextMatcher.

PatternMatcher
const boldMatcher = PatternMatcher(r'\*\*(.+?)\*\*');
final parser = TextParser(matchers: [boldMatcher]);
Custom matcher class

It is also possible to create a matcher class by extending TextMatcher.

Below is an example of a matcher that parses the HTML <a> tags into a set of the href value and the link text.

class ATagMatcher extends TextMatcher {
  const ATagMatcher()
      : super(
          r'\<a\s(?:.+?\s)*?href="(.+?)".*?\>'
          r'\s*(.+?)\s*'
          r'\</a\>',
        );
}
const text = '''
<a class="foo" href="https://example.com/">
  Content inside tags
</a>
''';

final parser = TextParser(
  matchers: const [ATagMatcher()],
  dotAll: true,
);
final elements = parser.parseSync(text, onlyMatches: true);
print(elements.first.groups);

Output:

[https://example.com/, Content inside tags]
ExactMatcher

ExactMatcher escapes reserved characters of RegExp so that those are used as regular characters. The parser extracts the substrings that exactly match any of the strings in the list passed as the argument.

TextParser(
  matchers: [
    // 'e.g.' matches only 'e.g.', not 'edge' nor 'eggs'.
    ExactMatcher(['e.g.', 'i.e.']),
  ],
)
Groups

Each TextElement in a parse result has the property of groups. It is a list of strings that have matched the smaller pattern inside every set of parentheses ( ).

Below is an example of a pattern that matches a Markdown style link.

r'\[(.+?)\]\((.*?)\)'

This pattern has two sets of parentheses; (.+?) in \[(.+?)\] and (/*?) in \((.*?)\). When this matches [foo](bar), the first set of parentheses captures "foo" and the second set captures "bar", so groups results in ['foo', 'bar'].

Tip:

If you want certain parentheses to be not captured as a group, add ?: after the opening parenthesis, like (?:pattern) instead of (pattern).

Named groups

Named groups are captured too, but their names are lost in the resulting groups list. Below is an example where a single match pattern contains capturing of both unnamed and named groups.

final parser = TextParser(
  matchers: const [PatternMatcher(r'(?<year>\d{4})-(\d{2})-(?<day>\d{2})')],
);
final elements = parser.parseSync('2020-01-23');
print(elements.first);

Output:

TextElement(matcherType: PatternMatcher, matcherIndex 0, offset: 0, text: 2020-01-23, groups: [2020, 01, 23])
RegExp options

How a regular expression is treated can be configured in the TextParser constructor.

  • multiLine
  • caseSensitive
  • unicode
  • dotAll

These options are passed to the constructor of RegExp internally, so refer to its document for information.

所屬分類

依賴

依賴清單 1 項

原始碼儲存庫

使用此套件的專案