最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Native: <string>.matchAll is not a function - Stack Overflow

programmeradmin1浏览0评论

I get a weird error when running my React Native app:

Some sample code:

const { url } = <ining object>;
const reURL   = <my regex>;

console.debug('url:', url);
console.debug('typeof url:', typeof url);

matches = [...url.matchAll(reURL)];

Log output:

url: <as expected>
typeof url: string

Error message:

TypeError: url.matchAll is not a function. (In 'url.matchAll(reURL)', 'url.matchAll' is undefined)

Everything works fine on iOS, the error only occurs on Android.

Pretty up to date environment, updated all npm packages a couple of days ago.

Does anyone have the slightest idea where to even begin searching for a solution ?

I get a weird error when running my React Native app:

Some sample code:

const { url } = <ining object>;
const reURL   = <my regex>;

console.debug('url:', url);
console.debug('typeof url:', typeof url);

matches = [...url.matchAll(reURL)];

Log output:

url: <as expected>
typeof url: string

Error message:

TypeError: url.matchAll is not a function. (In 'url.matchAll(reURL)', 'url.matchAll' is undefined)

Everything works fine on iOS, the error only occurs on Android.

Pretty up to date environment, updated all npm packages a couple of days ago.

Does anyone have the slightest idea where to even begin searching for a solution ?

Share Improve this question asked Nov 20, 2020 at 19:11 sscssc 9,92310 gold badges70 silver badges101 bronze badges 1
  • Does this answer your question? RegEx to extract all matches from string using RegExp.exec – Kia Kaha Commented Nov 7, 2022 at 11:52
Add a ment  | 

4 Answers 4

Reset to default 1

I have the same issue. String.matchAll does not work for Android. You should use match instead matchAll.

Example:

const regex = new RegExp(text, 'ig');
const arr = string.match(regex);

You will get an array match regex

You can use string.prototype.matchall to polyfill.

https://www.npmjs./package/string.prototype.matchall

import matchAll from 'string.prototype.matchAll'

matchAll.shim()

For us, this issue was solved by conditionally evaluating matchAll:

ourSring.matchAll?.(expr);

Our working theory is that the first time this method is accessed, some native async regex initialization is run, but takes some time to bind the method, resulting in undefined matchAll method. Subsequent evaluations work properly for us.

Replacing the call to str.matchAll(regex) with the recursive function in this answer did the job perfectly for me.

Pasting here the function with TS support for pleteness:

/**
 * Recursive function which replaces the usage of `str.matchAll(regex)` which happens to be troublesome on Android once piled.
 * @param regex - regex expression to be executed. If passed with the `/g` global flag the result will return all matches.
 * @param str - string value to be searched for matches by the regex expression
 * @param matches - parameter used to pass on the current resulting array through recursion iterations
 * @returns array of all matches found while executing the regex
 */
export function findAllMatches(regex: RegExp, str: string, matches: RegExpExecArray[] = []) {
  const res = regex.exec(str)
  res && matches.push(res) && findAllMatches(regex, str, matches)
  return matches
}

Ensuring nobody in the codebase would try to use matchAll again could be achieved by adding the following es-lint rule:

"no-restricted-syntax": ["error", {
   "selector": "CallExpression[callee.property.name='matchAll']",
   "message": "You should use the findAllMatches function instead."
}]
发布评论

评论列表(0)

  1. 暂无评论