url: drop digit-bridge requirement, leading (/+/0 alone is enough
`0731098515` is a real local-format phone (trunk-prefix 0, no separators) but the previous rule required a digit-separator-digit transition and rejected it. The leading-char gate + whitespace boundary already filter the bare-digit false positives we cared about (`1778840642934`, `order-…`, `smoke-original-…`), so drop the bridge check.
This commit is contained in:
@@ -254,7 +254,7 @@ bool _hasSigil(String text) {
|
|||||||
// count. 64 is well above any real chat density.
|
// count. 64 is well above any real chat density.
|
||||||
const int _kMaxMatchesPerMessage = 64;
|
const int _kMaxMatchesPerMessage = 64;
|
||||||
|
|
||||||
/// Drop phone candidates that don't look like real phones. Three checks:
|
/// Drop phone candidates that don't look like real phones. Two checks:
|
||||||
/// 1. The character immediately before the match (if any) must be
|
/// 1. The character immediately before the match (if any) must be
|
||||||
/// whitespace. Anything else — letter, digit, `-`, `:`, `/`, … —
|
/// whitespace. Anything else — letter, digit, `-`, `:`, `/`, … —
|
||||||
/// means the digits are glued to surrounding text (identifiers
|
/// means the digits are glued to surrounding text (identifiers
|
||||||
@@ -262,16 +262,13 @@ const int _kMaxMatchesPerMessage = 64;
|
|||||||
/// 2. The slice must start with `(`, `+`, or `0`. International
|
/// 2. The slice must start with `(`, `+`, or `0`. International
|
||||||
/// numbers begin with `+`, US-style begins with `(area)`, most
|
/// numbers begin with `+`, US-style begins with `(area)`, most
|
||||||
/// domestic formats outside the US use a `0` trunk prefix.
|
/// domestic formats outside the US use a `0` trunk prefix.
|
||||||
/// 3. The slice must look formatted: either a leading `+` (E.164) or
|
|
||||||
/// a digit-separator-digit transition (`555-1234`). A bare digit
|
|
||||||
/// run with no internal separator stays unmatched.
|
|
||||||
List<UrlMatch> _tightenPhoneMatches(List<UrlMatch> matches, String text) {
|
List<UrlMatch> _tightenPhoneMatches(List<UrlMatch> matches, String text) {
|
||||||
if (matches.isEmpty) return matches;
|
if (matches.isEmpty) return matches;
|
||||||
final out = <UrlMatch>[];
|
final out = <UrlMatch>[];
|
||||||
for (final m in matches) {
|
for (final m in matches) {
|
||||||
if (m.kind == UrlMatchKind.phone &&
|
if (m.kind == UrlMatchKind.phone &&
|
||||||
(!_phoneLeftBoundaryOk(text, m.start) ||
|
(!_phoneLeftBoundaryOk(text, m.start) ||
|
||||||
!_phoneSliceIsFormatted(text, m.start, m.end))) {
|
!_phoneLeadingCharOk(text, m.start, m.end))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
out.add(m);
|
out.add(m);
|
||||||
@@ -292,36 +289,14 @@ bool _phoneLeftBoundaryOk(String text, int start) {
|
|||||||
c == 0x2029 /* paragraph separator */;
|
c == 0x2029 /* paragraph separator */;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _phoneSliceIsFormatted(String text, int start, int end) {
|
bool _phoneLeadingCharOk(String text, int start, int end) {
|
||||||
final hi = end > text.length ? text.length : end;
|
final hi = end > text.length ? text.length : end;
|
||||||
final lo = start < 0 ? 0 : start;
|
final lo = start < 0 ? 0 : start;
|
||||||
if (lo >= hi) return false;
|
if (lo >= hi) return false;
|
||||||
final first = text.codeUnitAt(lo);
|
final first = text.codeUnitAt(lo);
|
||||||
if (first != 0x28 /* ( */ &&
|
return first == 0x28 /* ( */ ||
|
||||||
first != 0x2B /* + */ &&
|
first == 0x2B /* + */ ||
|
||||||
first != 0x30 /* 0 */) {
|
first == 0x30 /* 0 */;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (first == 0x2B /* + */) return true;
|
|
||||||
// 0 = pre-digit, 1 = digit run, 2 = separator after digit.
|
|
||||||
int state = 0;
|
|
||||||
for (int i = lo; i < hi; i++) {
|
|
||||||
final c = text.codeUnitAt(i);
|
|
||||||
final isDigit = c >= 0x30 && c <= 0x39;
|
|
||||||
final isSep = c == 0x20 /* space */ ||
|
|
||||||
c == 0x2D /* - */ ||
|
|
||||||
c == 0x28 /* ( */ ||
|
|
||||||
c == 0x29 /* ) */ ||
|
|
||||||
c == 0x2E /* . */;
|
|
||||||
if (state == 0 && isDigit) {
|
|
||||||
state = 1;
|
|
||||||
} else if (state == 1 && isSep) {
|
|
||||||
state = 2;
|
|
||||||
} else if (state == 2 && isDigit) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UrlMatch> _decode(Uint8List buf) {
|
List<UrlMatch> _decode(Uint8List buf) {
|
||||||
|
|||||||
Reference in New Issue
Block a user