IsMatch、Match 和 MatchAll 函数

适用于:画布应用模型驱动应用 Power Platform CLI

测试匹配项或根据模式提取文本字符串的某些部分。

描述

IsMatch 函数用于测试文本字符串是否与包含普通字符、预定义模式或正则表达式的某种模式相符。 MatchMatchAll 函数返回匹配的内容,包括子匹配项。

使用 IsMatch 函数可验证用户在 Text input 控件中输入的内容。 例如,可以在将结果保存到数据源中之前验证用户输入的电子邮件地址是否有效。 如果输入的内容与条件不符,可添加其他控件提示用户更正输入。

使用 Match 可以提取与模式匹配的第一个文本字符串,使用 MatchAll 可以提取与模式匹配的所有文本字符串。 您还可以提取子匹配项来分析复杂的字符串。

Match 返回找到的第一个匹配项的信息记录,MatchAll 返回找到的每个匹配项的记录表。 记录包含:

Column 类型​​ 说明
命名子匹配项 文本 每个命名子匹配都将有自己的列。 通过在正则表达式中使用 (?<name>...) 创建命名子匹配项。 如果命名子匹配项与预定义列(下方)之一具有相同名称,子匹配项优先,并生成警告。 若要避免此警告,请重命名子匹配项。
FullMatch 文本 匹配的所有文本字符串。
StartMatch 号码 匹配项在输入文本字符串中的开始位置。 字符串的第一个字符返回 1。
SubMatches 单列文本表(Value 列) 命名和未命名子匹配项的表按它们在正则表达式中出现的顺序排列。 通常,命名子匹配项更易于使用,建议使用。 使用 ForAll 函数或 Last( FirstN( ... ) ) 函数可以处理单独的子匹配项。 如果在正则表达式中未定义任何子匹配项,此表将存在但为空。

这些函数支持 MatchOptions。 默认情况下:

  • 这些函数执行区分大小写的匹配。 使用 MatchOptions.IgnoreCase 执行不区分大小写的匹配。
  • IsMatch 匹配整个文本字符串 (Complete MatchOption),而 MatchMatchAll 在文本字符串中的任意位置搜索匹配项 (Contains MatchOption)。 请根据您的情况使用 CompleteContainsBeginsWithEndsWith

如果文本字符串与模式相符,则 IsMatch 返回 true,否则,返回 false。 如果没有找到可以使用 IsBlank 函数测试的匹配项,Match 将返回 blank。 如果没有找到可以使用 IsEmpty 函数测试的匹配项,MatchAll 将返回一个空表。

如果您使用 MatchAll 拆分文本字符串,请考虑使用 Split 函数,该函数使用起来更简单、更快捷。

模式

使用这些函数的关键在于描述要匹配的模式。 您可以组合使用以下文本字符串来描述模式:

  • 普通字符,如 "abc""123"
  • 预定义模式,如 LetterMultipleDigitsEmail。 (Match 枚举定义了这些模式。)
  • 正则表达式代码,如 "\d+\s+\d+""[a-z]+"

通过使用字符串连接运算符 & 可以组合这些元素。 例如,"abc" & Digit & "\s+" 是一个有效的模式,它表示首先要与字符“a”、“b”和“c”匹配,后面跟一个从 0 到 9 的数字,后面再跟至少一个空格字符。

普通字符

最简单的模式是一系列要完全匹配的普通字符。

例如,当与 IsMatch 函数一起使用时,字符串“Hello”与模式 "Hello" 完全匹配。 不多不少,正好相符。 字符串“hello!”就与这个模式不匹配,因为它的末尾有一个感叹号,并且字母“h”的大小写错误。 (有关修改这种行为的方法,请参阅 MatchOptions。)

模式语言中有一些保留字符,这些字符有特殊的用途。 要使用这些字符,请使用 \(反斜杠)作为前缀,这表示应将后面的字符当作普通字符,您也可以使用此主题后面介绍的预定义模式之一。 下表列出了这些特殊字符:

特殊字符 说明
. 圆点或句点
? 问号
* 星号
+
( ) 括号
[ ] 方括号
{ } 大括号
^ 插入符号
$ 美元符号
| 竖线
\ 反斜杠

例如,可以使用在问号前加一个反斜杠的模式 "Hello\?" 来匹配“Hello?”。

预定义模式

预定义模式提供了一种简单方法来匹配一组字符中的一个字符或一个多字符序列。 使用字符串连接运算符 & 可将您自己的文本字符串与 Match 枚举中的模式进行组合:

Match 枚举 描述 正则表达式
Any 匹配任何字符。 .
Comma 匹配逗号。 ,
Digit 匹配单个数字(“0”到“9”)。 \d
电子邮件 匹配包含“at”符号(“@”)和包含点(“.”)的域名的电子邮件地址 .+\@.+\\.[^\\.]{2,}
Hyphen 匹配连字符。 \-
LeftParen 匹配左圆括号“(”。 \(
Letter 匹配一个字母。 \p{L}
MultipleDigits 匹配一个或多个数字。 \d+
MultipleLetters 匹配一个或多个字母。 \p{L}+
MultipleNonSpaces 匹配不包含空白(不是空格、制表符或换行符)的一个或多个字符。 \S+
MultipleSpaces 匹配可间断(包含空格、制表符或换行符)的一个或多个字符。 \s+
NonSpace 匹配不包含空白的单个字符。 \S
OptionalDigits 配零个、一个或多个数字。 \d*
OptionalLetters 匹配零个、一个或多个字母。 \p{L}*
OptionalNonSpaces 匹配不包含空白的零个、一个或多个字符。 \S*
OptionalSpaces 匹配包含空白的零个、一个或多个字符。 \s*
Period 匹配句点或圆点(“.”)。 \.
RightParen 匹配右圆括号“)”。 \)
Space 匹配包含空白的字符。 \s
Tab 匹配制表符。 \t

例如,模式 "A" & MultipleDigits 与字母“A”后跟一个或多个数字的形式匹配。

正则表达式

这些函数使用的模式是正则表达式。 此主题前面介绍的普通字符和预定义模式可以帮助您构建正则表达式。

正则表达式的功能非常强大,许多编程语言中都有提供,并且用途广泛。 它们通常可能看上去像是随机的标点符号序列。 本文没有详细介绍正则表达式的每个方面,不过网络上有大量的信息、教程和工具可用。

正则表达式有不同的方言,Power Apps 使用 JavaScript 方言的一种变体。 有关语法的介绍,请参阅正则表达式语法。 支持命名子匹配项(有时称为命名捕获组):

  • 名子匹配项:(?<name> ...)
  • 命名反向引用:\k<name>

在此主题前面的 Match 枚举表中,每个枚举与其对应的正则表达式出现在同一行中。

匹配选项

您可以通过指定一个或多个选项(可使用字符串连接运算符 (&) 进行组合)修改这些函数的行为。

MatchOptions 枚举 Description 对正则表达式的影响
MatchOptions.BeginsWith 模式必须与文本的开头匹配。 在正则表达式的开头添加 ^
MatchOptions.Complete IsMatch 的默认值。 模式必须与整个文本字符串从头到尾完全匹配。 在正则表达式的开头添加 ^,并且在末尾添加 $
MatchOptions.Contains MatchMatchAll 的默认值。 模式必须出现在文本中,但不必与开头或结尾匹配。 不修改正则表达式。
MatchOptions.EndsWith 模式必须与文本字符串的末尾匹配。 在正则表达式的末尾添加 $
MatchOptions.IgnoreCase 将大写和小写字母视为相同。 默认情况下,匹配时区分大小写。 不修改正则表达式。 此选项等效于正则表达式的标准“i”修饰符。
MatchOptions.Multiline 匹配多行。 不修改正则表达式。 此选项等效于正则表达式的标准“m”修饰符。

使用 MatchAll 等效于对正则表达式使用标准的“g”修饰符。

语法

IsMatch( Text, Pattern [, Options ] )

  • Text – 必需。 要测试的文本字符串。
  • Pattern – 必需。 要作为文本字符串测试的模式。 连接 Match 枚举定义的预定义模式或提供正则表达式。 Pattern 必须是一个常数公式,且没有任何变量、数据源或其他随应用运行而变化的动态引用。
  • Options – 可选。 MatchOptions 枚举值的文本字符串组合。 默认情况下,使用 MatchOptions.Complete

Match( Text, Pattern [, Options ] )

  • Text – 必需。 要匹配的文本字符串。
  • Pattern – 必需。 要作为文本字符串匹配的模式。 连接 Match 枚举定义的预定义模式或提供正则表达式。 Pattern 必须是一个常数公式,且没有任何变量、数据源或其他随应用运行而变化的动态引用。
  • Options – 可选。 MatchOptions 枚举值的文本字符串组合。 默认情况下,使用 MatchOptions.Contains

MatchAll( Text, Pattern [, Options ] )

  • Text – 必需。 要匹配的文本字符串。
  • Pattern – 必需。 要作为文本字符串匹配的模式。 连接 Match 枚举定义的预定义模式或提供正则表达式。 Pattern 必须是一个常数公式,且没有任何变量、数据源或其他随应用运行而变化的动态引用。
  • Options – 可选。 MatchOptions 枚举值的文本字符串组合。 默认情况下,使用 MatchOptions.Contains

IsMatch 示例

普通字符

假设应用包含一个名为 TextInput1Text input 控件。 用户在这个控件中输入的值存储在数据库中。

用户在 TextInput1 中输入 Hello world

公式 描述 结果
IsMatch( TextInput1.Text, "Hello world" ) 测试用户输入的内容是否与字符串“Hello world”完全匹配。 true
IsMatch( TextInput1.Text, "Good bye" ) 测试用户输入的内容是否与字符串“Good bye”完全匹配。 false
IsMatch( TextInput1.Text, "hello", Contains ) 测试用户输入的内容是否包含单词“hello”(区分大小写)。 false
IsMatch( TextInput1.Text, "hello", Contains & IgnoreCase ) 测试用户输入的内容是否包含单词“hello”(不区分大小写)。 true

预定义模式

公式 描述 结果
IsMatch( "123-45-7890", Digit & Digit & Digit & Hyphen & Digit & Digit & Hyphen & Digit & Digit & Digit & Digit ) 匹配美国社会安全号码 true
IsMatch( "joan@contoso.com", Email ) 匹配电子邮件地址 true
IsMatch( "123.456", MultipleDigits & Period & OptionalDigits ) 匹配一个数字序列,后跟一个句点,后面再跟零个或多个数字。 true
IsMatch( "123", MultipleDigits & Period & OptionalDigits ) 匹配一个数字序列,后跟一个句点,后面再跟零个或多个数字。 文本中没有匹配的句点,因此该模式不匹配。 false

正则表达式

公式 描述 结果
IsMatch( "986", "\d+" ) 匹配大于零的整数。 true
IsMatch( "1.02", "\d+(\.\d\d)?" ) 匹配正货币金额。 如果输入的内容包含小数点,则小数点后还要有两个数字字符。 例如,3.00 有效,但 3.1 无效。 true
IsMatch( "-4.95", "(-)?\d+(\.\d\d)?" ) 匹配正或负货币金额。 如果输入的内容包含小数点,则小数点后还要有两个数字字符。 true
IsMatch( "111-11-1111", "\d{3}-\d{2}-\d{4}" ) 匹配美国社会安全号码。 验证提供的输入字段的格式、类型和长度。 要匹配的字符串必须包含三个数字字符,后跟一个短划线,再跟两个数字字符,再跟一个短划线,最后跟四个数字字符。 true
IsMatch( "111-111-111", "\d{3}-\d{2}-\d{4}" ) 与上例相同,但其中一个连字符的位置不对。 false
IsMatch( "AStrongPasswordNot", "(?!^[0-9]\*$)(?!^[a-zA-Z]\*$)([a-zA-Z0-9]{8,10})" ) 验证强密码,除包含至少一个数字和至少一个字母字符外,还必须包含 8、9 或 10 个字符。 字符串不能包含特殊字符。 false

Match 和 MatchAll 示例

公式 描述 结果
Match( "Bob Jones <bob.jones@contoso.com>", "<(?<email>" & Match.Email & ")>" 仅提取联系信息的电子邮件部分。 {
email: "bob.jones@contoso.com",
FullMatch: "<bob.jones@contoso.com>",
SubMatches: [ "bob.jones@contoso.com" ],
StartMatch: 11
}
Match( "Bob Jones <InvalidEmailAddress>", "<(?<email>" & Match.Email & ")>" 仅提取联系信息的电子邮件部分。 找不到合法地址(没有 @ 符号),因此函数返回blank blank
Match( Language(), "(<language>\w{2})(?:-(?<script>\w{4}))?(?:-(?<region>\w{2}))?" ) 提取 Language 函数返回的语言标记的语言、脚本或区域部分。 这些结果反映的是美国;有关更多示例,请参阅 Language 函数文档(?: 运算符将字符分组,而不创建另一个子匹配项。 {
language: "en",
script: blank,
region: "US",
FullMatch: "en-US",
SubMatches: [ "en", "", "US" ],
StartMatch: 1
}
Match( "PT2H1M39S", "PT(?:<hours>\d+)H)?(?:(?<minutes>\d+)M)?(?:(?<seconds>\d+)S)?" ) 从 ISO 8601 持续时间值中提取小时、分钟和秒。 提取的数字仍在文本字符串中;使用 Value 函数将文本字符串转换为数字,然后再对其执行数学运算。 {
hours: "2",
minutes: "1",
seconds: "39",
FullMatch: "PT2H1M39S",
SubMatches:["2","1","39"],
StartMatch: 1
}

让我们深入探索一下最后一个示例。 如果要使用 Time 函数将此字符串转换为日期/时间值,则必须逐个传递命名子匹配项。 为此,您可以对 Match 返回的记录运行 With 函数:

With(
    Match( "PT2H1M39S", "PT(?:(?<hours>\d+)H)?(?:(?<minutes>\d+)M)?(?:(?<seconds>\d+)S)?" ),
   Time( Value( hours ), Value( minutes ), Value( seconds ) )
)

对于这些示例,添加一个 Button 控件,将其 OnSelect 属性设置为此公式,然后选择按钮:

Set( pangram, "The quick brown fox jumps over the lazy dog." )
公式 描述 结果
Match( pangram, "THE", IgnoreCase ) pangram 变量包含的文本字符串中查找“THE”的所有匹配项。 此字符串包含两个匹配项,但仅返回第一个匹配项,因为您使用的是 Match,而不是 MatchAll。 SubMatches 列是空的,因为没有定义子匹配项。 {
FullMatch: "The",
SubMatches: [ ],
StartMatch: 32
}
MatchAll( pangram, "the" ) pangram 变量包含的文本字符串中找到“the”的所有匹配项。 此测试区分大小写,因此仅找到“the”的第二个实例。 SubMatches 列是空的,因为没有定义子匹配项。 pangram 的 MatchAll。
MatchAll( pangram, "the", IgnoreCase ) pangram 变量包含的文本字符串中找到“the”的所有匹配项。 在此例中,测试不区分大小写,因此找到了该单词的全部两个实例。 SubMatches 列是空的,因为没有定义子匹配项。 带有 IgnoreCase 的 MatchAll。
MatchAll( pangram, "\b\wo\w\b" ) 查找所有三个字母的单词,中间带有“o”。 请注意,“brown”被排除在外,因为它不是三个字母的单词,因此未匹配“\b”(单词边界)。 带有 b、wo、w 和 b 的 pangram 的 MatchAll。
Match( pangram, "\b\wo\w\b\s\*(?<between>\w.+\w)\s\*\b\wo\w\b" ) 匹配“fox”和“dog”之间的所有字符。 {
between: "jumps over the lazy",
FullMatch: "fox jumps over the lazy dog",
SubMatches: [ "jumps over the lazy" ],
StartMatch: 17
}

要查看库中的 MatchAll 的结果,请执行以下操作:

  1. 在空屏幕中,插入一个空白垂直 Gallery 控件。

  2. 将库的 Items 属性设置为 MatchAll( pangram, "\w+" )MatchAll( pangram, MultipleLetters )

    项库。

  3. 在 Gallery 控件的中间选择“从‘插入’选项卡添加项”,以选择库的模板。

  4. Label 控件添加到库的模板中。

  5. 将标签的 Text 属性设置为 ThisItem.FullMatch

    库已填充了我们的示例文本中的每个单词。 调整库的模板和 Label 控件的大小,以在一个屏幕上查看所有单词。

    Text 属性。