用于自动完成功能的正则表达式



我正在编写一个具有自动完成功能的搜索栏,该功能已连接到端点。我正在使用正则表达式来确定我在搜索栏中键入的查询中的"上下文"。这三个上下文是"属性"、"值"和"运算符"。允许的两个运算符是"AND"和"OR"。下面是一个示例查询示例。

颜色:蓝色和尺寸:"女士大号"(<- 多字值或属性名称用引号引起来)

在 Blue 后面放一个空格后,我需要我的正则表达式匹配,如果用户开始键入"A/AN/AND/O/OR",我需要它匹配。一旦他们在运算符后面放了一个空格,我需要它停止匹配。

这是我想出的表达方式。

const contextIsOperator = /[wds"]+: *[wsd"]+ [w]*$/

一旦我在"蓝色"之后放置一个空格,它就会匹配,但与我在此之后放置的所有内容匹配。如果我用 + 替换表达式中的最后一个*,当我在"Blue"之后放置一个空格并开始手动键入其中一个运算符时,它会起作用,但如果我在"Blue"之后只有一个空格,则不起作用。

我脑子里用文字写的模式是:

  1. 一个或多个字符/数字/空格/引号的组
  2. 后跟一个冒号
  3. 后跟一个可选空格
  4. 后跟另一组一个或多个字符/数字/空格/引号
  5. 后跟一个空格(在值之后)
  6. 后跟一个或多个字符(这是运算符)

如何解决此问题?

[w]*更改为仅匹配ANDOR或其前缀之一的内容。然后,您可以使用?将其设置为可选

[ws"]+: *[ws"]+ (A|AN|AND|O|OR)?$

演示

请注意,Size: Women's Large不会匹配这一点,因为撇号不在w中;它只匹配字母、数字和下划线。您需要将要在这些字段中允许的任何其他标点字符添加到字符集中。

是,你的语言没有足够的确定性,无法使用正则表达式正确建模。 话虽如此,您可以采取两种方法:

  1. 要求所有值(:之后和运算符之前的内容)括在引号中
  2. 构建一个简单的状态机,可以更智能地解析数据。 (谷歌有限状态机解析器)

如果选择使用第一种方法,则可以使用以下正则表达式:

^(("?[ws]+"?): ?("[ws']+")( (AND|OR) )?)+$

我会解释不同的组件,但 regex101 已经为我提供了非常好的视觉效果和细节。

编辑:这是最后一个,在这里检查单元测试

const regex = /((("[ws"'']+(?="b))"|[w"'']+):s?(("[ws"'']+(?="b))"|[w"'']+)s(AND|OR)(?=bs))+/

怪物应该匹配(NOTE: QUOTED KEYS/VALUES MUST BE DOUBLE QUOTED):

Color: Blue AND "Size5":"Women's Large"
"weird KEy":regularvalue OR otherKey: "quoted value"

来吧,试试这个

^(?:"[^"]*"|[^s:]+):[ ](?:"[^"]*"|[^s:]+)[ ](?:A(?:N(?:D(?:[ ](*SKIP)(?!))?)?)?|O(?:R(?:[ ](*SKIP)(?!))?)?)?

https://regex101.com/r/neUQ0g/1

解释

^                             # BOS
(?:                           # Attribute
"
[^"]* 
"
|  
[^s:]+ 
)
:
[ ] 
(?:                           # Value
"
[^"]* 
"
|  
[^s:]+ 
)
[ ]                           # Start matching after Attribute: Value + space
(?:                           # Operator
A
(?:
N
(?:
D 
(?:                           # Stop matching after 'AND '
[ ] 
(*SKIP) 
(?!)
)?
)?
)?
|  
O 
(?:
R 
(?:                           # Stop matching after 'OR '
[ ] 
(*SKIP)                    
(?!)
)?
)?
)?

最新更新