是否可以使用正则表达式匹配字符串开头的s-expression。就像我有这样的字符串:
(foo (bar)) "baz" "quux"
我要提取
(foo (bar))
它还应该能够从字符串中提取第一个s-expression,如下所示:
(foo (bar)) (foo bar)
和
(foo ")" "bar")
是否可以使用正则表达式?
答案 0 :(得分:2)
如果没有转义序列,您可以使用
^(\((?>"[^"]*"|[^()]|(?1))*\))
请参阅regex demo
模式匹配:
^
- 字符串开头(\((?>"[^"]*"|[^()]|(?1))*\))
- 第1组,其模式将被递归,匹配
\(
- 开场(
(?>"[^"]*"|[^()]|(?1))*
- 零次或多次出现:
"[^"]*"
- 以"
开头的文字,后跟除"
以外的零个或多个字符,以"
结尾|
- 或[^()]
- 除(
和)
|
- 或(?1)
- 整个第1组模式(递归)\)
- 结束)
。注意:如果可以转义序列,那么正则表达式不是一个好工作。如果您将"[^"]*"
替换为"[^\\"]*(?:\\.[^"\\]*)*"
,那会更好,但仍然不安全。
答案 1 :(得分:0)
更高效的正则表达式:
^(\([^()"]*(?:"[^"]*"[^()"]*)*(?1)*\))
说明:
^ # Asserts beginning of line
( # Start of capturing group (1)
\([^()"]* # A sequence of `(...` up to a double quotation mark or `)`
(?:"[^"]*"[^()"]*)* # Any string within double quotation marks
(?1)* # Recurs a similar sequence of `(...`
\) # End of match
) # End of capturing group (1)
如果@Wiktor在评论中指出的那些模式是有效的,那么这个模式 - 无论多长 - 都可以工作并保持效率:
^(\([^()"]*(?1)*[^()"]*(?:"[^"]*"[^()"]*)*(?1)*\))
Live demo(参见引擎采取的步骤数)