3

我想知道是否有人可以为我提供解析字符串所需的正则表达式,例如:

'foo bar "多字标签"'

进入标签数组,如:

["foo","bar","多字标签"]

谢谢

4

6 回答 6

7

在红宝石中

scan(/\"([\w ]+)\"|(\w+)/).flatten.compact

例如

"foo bar \"multiple words\" party_like_1999".scan(/\"([\w ]+)\"|(\w+)/).flatten.compact
=> ["foo", "bar", "multiple words", "party_like_1999"]
于 2009-01-20T01:19:58.083 回答
2

您可以实施扫描仪来执行此操作。例如,在 Python 中,它看起来像这样:

import re
scanner = re.Scanner([
    (r"[a-zA-Z_]\w*", lambda s,t:t),       # regular tag
    (r"\".*?\"",      lambda s,t:t[1:-1]), # multi-word-tag
    (r"\s+",          None),               # whitespace not in multi-word-tag
    ])
tags, _ = scanner.scan('foo bar "multiple word tag"')
print tags
# ['foo', 'bar', 'multiple word tag']

这称为词法分析。

于 2009-01-20T00:43:42.197 回答
0

首先,我建议使用split()方法/函数而不是正则表达式来执行此操作。大多数语言都有这样的东西,您可以调用它来将字符串拆分为单词(由空格分隔),并且您通常可以指定要将其拆分为多少部分的上限。所以一般来说,

split('foo bar "multiple word tag"', ' ', 3)

其中 3 表示不超过 3 个部分,适用于您的示例。您可以使用trim()orstrip()方法/函数(或编写一个)来删除任何前导和尾随引号。

如果你打算用正则表达式来做,也许是因为每一行可能有可变数量的标签,在某种程度上它取决于你到底用什么来做解析,因为不同的正则表达式引擎有时有不同的方式代表相同的事物。而且我认为它不能仅用一个普通的旧正则表达式来完成。你需要一些代码来配合它。例如,这是一个使用 Perl 兼容的正则表达式(或类似的东西,无论如何)的(伪?)伪代码解决方案:

pos = 0;
while pos < length(string):
    # match(regular expression, string to search, starting position for the search)
    m = match(/\s*(".+?"|\S+)?\s*/, string, pos);
    tag = m.group(1).strip('"');
    # process the tag

对于它的价值,我可能会使用 DFA(离散有限自动机)来执行此操作,它逐个字符地遍历字符串,将每个字符附加到缓冲区并在到达标记末尾时刷新缓冲区(或者是因为空格或右引号)。也许只有我一个人,但我觉得这是一个非常简单的解析任务,就 DFA 状态而言(在我看来)会更容易理解。

于 2009-01-20T00:48:00.550 回答
0

适用于任何 match->array 函数的通用正则表达式:

(?<=")[^"]+|\w+


(如果不只允许使用字母数字和引号,使用\S+而不是\w+可能有意义。)


红宝石示例:

myarray = mystring.scan(/(?<=\")[^\"]+|\w+/)

(未经测试)

于 2009-01-20T00:49:40.190 回答
0

我们开始(Perl 风格):

^(?:"([^"]*?)"|(\S+?)|\s*?)*$

解释:

^                    // from begginning                 
 (?:                  // non-capturing group of three alternatives
    "([^"]*?)"   // capture "tag"                                               "
 |
    (\S+?)        // capture tag
 |
    \s*?            // ignore whitespace
 )*                  
$                    // until the end of the line
于 2009-01-20T01:06:33.963 回答
-1

正则表达式几乎肯定不会是您在这里寻找的解决方案。正则表达式可用于从较大的字符串中解析一组匹配的输入。例如,如果我只想从电子邮件地址中获取用户名,我可以使用以下正则表达式来获取数据

"^(?<username>[\w\d]+)@.*$"

该名称将出现在名称组“用户名”中

在您的情况下,您并没有尝试获取输入字符串的子集。您正在尝试匹配整个字符串的元素。在一天结束时,正则表达式只会说“是的,它匹配”或“不,它不匹配”。为了获取内容,您需要实际解析出字符串。

于 2009-01-20T00:35:59.203 回答