ChatGPT解决这个技术问题 Extra ChatGPT

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

在使用正则表达式模式搜索匹配项时,是否有一种简单的方法可以忽略目标字符串中的空格?例如,如果我的搜索是“cats”,我希望匹配“c ats”或“cat ts”。我无法事先去除空格,因为我需要找到匹配的开始和结束索引(包括任何空格)以突出显示该匹配并且任何空格都需要用于格式化目的。


C
Chris

您可以在正则表达式中的每个其他字符之间粘贴可选的空白字符 \s*。虽然被授予,但它会变得有点冗长。

/cats/ -> /c\s*a\s*t\s*s/


谢谢,听起来就是这样。但我刚刚意识到,如果它们跟随换行符,我只想要可选的空白字符。例如,“c\n ats”或“ca\n ts”应该匹配。但如果没有换行符,不希望“c ats”匹配。关于如何做到这一点的任何想法?
@Steven,在下面看看我是如何做到的,您可以轻松地将我的解决方案调整到此类特定情况。
@chris 我认为,这个正则表达式只对猫非常严格,它也可以用于任何这样的字母搜索:^([a-z]\s*)+$
K
Konrad Höffner

虽然公认的答案在技术上是正确的,但如果可能的话,一种更实用的方法是从正则表达式和搜索字符串中去掉空格。

如果您想搜索“我的猫”,而不是:

myString.match(/m\s*y\s*c\s*a\*st\s*s\s*/g)

做就是了:

myString.replace(/\s*/g,"").match(/mycats/g)

警告:您不能通过将所有空格替换为空字符串来在正则表达式上自动执行此操作,因为它们可能会出现在否定中,否则会使您的正则表达式无效。


A
Aurimas

解决史蒂文对萨姆杜菲尔的回答的评论

谢谢,听起来就是这样。但我刚刚意识到,如果它们跟随换行符,我只想要可选的空白字符。例如,“c\n ats”或“ca\n ts”应该匹配。但是如果没有换行符,不希望“c ats”匹配。关于如何做到这一点的任何想法?

这应该可以解决问题:

/c(?:\n\s*)?a(?:\n\s*)?t(?:\n\s*)?s/

请参阅 this page,了解与此匹配的“猫”的所有不同变体。

您也可以使用 conditionals 解决此问题,但它们在 javascript 风格的正则表达式中不受支持。


所以非常丑陋。一定会有更好的办法。
您可以通过以下方式使其在 JS 语法中更具可读性(尽管该技术适用于其他语言):new RegExp('cats'.split('').join('(?:\n\s*)?'))
正则表达式本身没有“宽容搜索”之类的东西,这太疯狂了。我与 RegEx 打交道已有 15 年了,但仍然一团糟:/
K
Kludge

您可以将 \s* 放在搜索字符串的每个字符之间,因此如果您正在寻找 cat,您可以使用 c\s*a\s*t\s*s\s*s

它很长,但您当然可以动态构建字符串。

您可以在此处看到它的工作原理:http://www.rubular.com/r/zzWwvppSpE


T
Tim Pietzcker

如果你只想允许空格,那么

\bc *a *t *s\b

应该这样做。要也允许选项卡,请使用

\bc[ \t]*a[ \t]*t[ \t]*s\b

如果您还想在 bobcatscatsup 等词中找到 cats,请删除 \b 锚点。


B
Bob

这种方法可用于自动执行此操作(以下示例性解决方案是在 python 中,尽管显然它可以移植到任何语言):

您可以事先去除空格并保存非空格字符的位置,以便以后可以使用它们来找出原始字符串中匹配的字符串边界位置,如下所示:

def regex_search_ignore_space(regex, string):
    no_spaces = ''
    char_positions = []

    for pos, char in enumerate(string):
        if re.match(r'\S', char):  # upper \S matches non-whitespace chars
            no_spaces += char
            char_positions.append(pos)

    match = re.search(regex, no_spaces)
    if not match:
        return match

    # match.start() and match.end() are indices of start and end
    # of the found string in the spaceless string
    # (as we have searched in it).
    start = char_positions[match.start()]  # in the original string
    end = char_positions[match.end()]  # in the original string
    matched_string = string[start:end]  # see

    # the match WITH spaces is returned.
    return matched_string

with_spaces = 'a li on and a cat'
print(regex_search_ignore_space('lion', with_spaces))
# prints 'li on'

如果你想更进一步,你可以构造匹配对象并返回它,所以使用这个助手会更方便。

而且这个功能的性能当然也可以优化,这个例子只是为了展示解决方案的路径。


这是唯一对我有用的。
j
jwriteclub

如果以及当您将动态值(例如数组循环中的“当前值”)作为正则表达式测试值传递时,接受的答案将不起作用。如果没有一些非常丑陋的正则表达式,您将无法输入可选的空格。因此,Konrad Hoffner 的解决方案在这种情况下会更好,因为它会同时去除 regest 和 test 空白字符串。将进行测试,就好像两者都没有空格一样。