0

我有以下格式的字符串:

'I had a great time with @[2468] and @[1357]! #[1111] #[2321]#[1212]'

我希望能够提取 @ 和 # 符号之间的数字,但我不想要包含的方括号。例如我想返回:

user_ids = [2468, 1357]
hash_tag_ids = [1111, 2321, 1212]

有任何想法吗?

4

2 回答 2

1

因为你想匹配所有出现的模式,所以string.scan方法就是你想要的。Scan 会自动返回与模式匹配的所有内容,因此您不需要使用“捕获组”(您在大多数正则表达式中看到的括号),但您确实需要使用“lookahead”和“lookbehind”来匹配一些没有将其包含在您的结果中。

您需要的两行是:

string.scan(/(?<=@\[)\d+(?=\])/).map(&:to_i) # => [2468, 1357]
string.scan(/(?<=#\[)\d+(?=\])/).map(&:to_i) # => [1111, 2321, 1212]
  • (?<=...)会创建一个“肯定的后视”,以确保前面的字符匹配...,但这些字符不包含在匹配的文本中。换句话说,(?<=@\[)将匹配“@[”,但“@[”不会包含在string.scan.
  • 注意左方括号,右方括号前面有一个斜线。这是因为方括号在正则表达式中具有特殊含义(它们创建一个“字符类”),但由于我们要匹配文字方括号,我们必须用斜杠“转义”它们。
  • \d+表示匹配 1 个或多个数字。
  • (?=...)创建一个“正向前瞻”,确保以下字符匹配...,但这些字符不包含在匹配的文本中。与上面的lookbehind 相同,但检查后面的字符而不是前面的字符。在这种情况下,(?=\])匹配“]”而不在返回的结果中包含“]” string.scan
  • string.scan将返回一个字符串数组。该.map(&:to_i)部分将string.to_i在每个字符串上运行以返回一个实际的整数值。
于 2013-10-01T23:21:41.673 回答
0
string.scan(/(?<=@\[)[^\]]*(?=\])/) # => ["2468", "1357"]
string.scan(/(?<=#\[)[^\]]*(?=\])/) # => ["1111", "2321", "1212"]
于 2013-10-01T23:04:12.967 回答