与正则表达式匹配时是不是可以忽略字符串中的字符

Posted

技术标签:

【中文标题】与正则表达式匹配时是不是可以忽略字符串中的字符【英文标题】:Is it possible to ignore characters in a string when matching with a regular expression与正则表达式匹配时是否可以忽略字符串中的字符 【发布时间】:2012-01-25 00:29:12 【问题描述】:

我想创建一个正则表达式,这样当我将字符串与字符串数组进行比较时,会返回匹配项,而正则表达式会忽略某些字符。

这是一个例子。考虑以下名称数组:


    "Andy O'Brien",
    "Bob O'Brian",
    "Jim OBrien",
    "Larry Oberlin"

如果用户输入“ob”,我希望应用程序将正则表达式谓词应用于数组,并且上述数组中的所有名称都会匹配(例如,忽略 ')。

我知道我可以运行两次匹配,第一次针对每个名称,第二次针对每个名称,并从字符串中删除忽略的字符。我宁愿通过单个正则表达式完成此操作,因此我不需要两次传递。

这可能吗?这是一个 ios 应用程序,我正在使用 NSPredicate。

编辑:使用说明

从最初的答案中,我意识到我并不清楚。上面的例子是一个具体的例子。我需要一个通用解决方案,其中名称数组是一个具有不同名称的大型数组,并且我匹配的字符串由用户输入。所以我不能硬编码像 [o]'?[b] 这样的正则表达式。

另外,我知道如何进行不区分大小写的搜索,所以不需要答案来关注它。只需要一个解决方案来忽略我不想匹配的字符。

【问题讨论】:

由于正则表达式依次应用于每个字符串,您可以简单地从字符串中删除所有要“忽略”的字符,然后将正则表达式应用于修改后的字符串。 【参考方案1】:

既然你已经放弃了所有显示它可以完成的方法的答案,你就剩下答案了:

不,这是不可能的。正则表达式没有“忽略”字符的选项。您唯一的选择是修改正则表达式以匹配它们,或者对源文本进行传递以摆脱您想要忽略的字符,然后与之匹配。 (当然,您可能会遇到将“清理”文本与实际源文本相关联的问题。)

【讨论】:

给定我的实现,我找到了一个合理的解决方案,一种通过源代码的变体来消除我不想匹配的字符。感谢您的意见。 这对我来说似乎太过分了。为什么不取搜索字符串,并指出“忽略”的字符可能在每个字符之后出现 0 次或 1 次?例如,如果用户输入字符串“oleary”,您可以将其转换为正则表达式 o'?l'?e'?a'?r'?y'? 。我想这会对性能产生非常负面的影响,但我不明白为什么它不起作用。 这就是问题所在。这是一段需要尽可能快的代码。在这方面,我现在的解决方案似乎还可以。谢谢。【参考方案2】:

如果我理解正确,您需要一种匹配字符“ob”的方法 1) 无论大小写如何,2) 无论它们之间是否有撇号。这应该很容易。

1) 使用不区分大小写的修饰符,或使用指定字母的大写和小写版本都可接受的正则表达式:[Oo][Bb]

2) 使用? 修饰符来指示一个字符可能出现一次或零次。 o'?b 将匹配“o'b”和“ob”。如果您想包含其他可能存在或不存在的字符,您可以使用撇号将它们分组。例如,o['-~]?b 将匹配“ob”、“o'b”、“o-b”和“o~b”。

所以完整的答案是[Oo]'?[Bb]

更新:OP 要求提供一种解决方案,该解决方案会导致给定字符在任意搜索字符串中被忽略。您可以通过在搜索字符串的每个字符后插入'? 来完成此操作。例如,如果为您提供搜索字符串oleary,您可以将其转换为o'?l'?e'?a'?r'?y'?。万无一失,尽管可能不是最佳性能。请注意,如果这是一个问题,这将匹配“o'leary”但也匹配“o'lea'r'y'”。

【讨论】:

谢谢,请参阅我对问题的编辑。我需要一个更通用的解决方案。 如果我对更新的理解正确,您希望能够在忽略撇号的同时搜索字符串。是对的吗?将搜索字符串分解为字符,在每个字符之间插入'?,并将结果字符串用作正则表达式是否有效?【参考方案3】:

在这种特殊情况下,只需将字符集作为可选字符放入正则表达式的中间即可。这特别有效,因为您的匹配字符串中只有两个字符,否则正则表达式可能会有点冗长。例如,不区分大小写匹配:

o[']*b

您可以在中间的该字符类中添加更多字符以忽略它们。请注意,* 匹配 任何 个字符(因此 O'''Brien 将匹配) - 对于单个实例,更改为 ?

o[']?b

【讨论】:

谢谢,请查看我对问题的编辑。我需要一个更通用的解决方案。 @XJones:那么你基本上只剩下 Phrogz 的解决方案了,因为你已经改变了问题,使其他一切都无效。 是的,再次抱歉,我不清楚。我不需要 SO 来做一些基本的事情,但我想你无法知道这一点。感谢您的宝贵时间。【参考方案4】:

您可以使用问号将特定字符设为可选,这意味着无论它们是否存在,它都会匹配,例如:

/o\'?b/

将匹配以上所有字符,在任一侧添加 .+ 以匹配所有其他字符,并用空格表示姓氏的开头:

/.+? o\'?b.+/

并使用不区分大小写的修饰符使其匹配,无论大小写。

【讨论】:

以上是关于与正则表达式匹配时是不是可以忽略字符串中的字符的主要内容,如果未能解决你的问题,请参考以下文章

如何忽略正则表达式主题字符串中的空格?

正则表达式匹配

正则表达式用来根据某种匹配模式寻找字符串中的某些单词。

忽略正则表达式中的撇号[重复]

如何检查字符串是不是与 node.js 中的任何正则表达式数组匹配?

如何检查字符串是不是与 Thymeleaf 中的正则表达式匹配?