1

这是我的困境...

我希望能够拆分如下所示的字符串:

/ban @User "because I told you so"

但是,使用空格、@ 或引号作为字符串分隔符的问题是用户名可能包含大量特殊字符。而且,很可能,这些特殊字符可能会与处理命令发生冲突。

例如:

/ban @Person" "because why not"

行不通,也不行

/ban @Person"name" "reason"

当我可以用来分割字符串的任何字符都可以很容易地被目标用户的名字模拟来破坏命令时,我如何才能准确地处理这样的事情?这甚至可能吗?老实说,RegExp 对我来说有点难以理解或看,所以如果这是一个简单的正则表达式修复,我深表歉意:(

非常感谢一个解决方案,我现在有一个工作处理器:

    var yourRegex = /^@(.*?) "([^"]+)"$/;

由于我已经可以删除 /ban(其他命令,如 /kick 等,因为它不只是这个命令)我只是将它从正则表达式中删除。我也将 @ 符号移出,因为我不需要它来定位用户。100% 有效:D

4

2 回答 2

1

试试这个:

/^\/ban (@.*?) "([^"]+)"$/

这将为您提供第一个子模式中的用户名(带有前导@符号,如果要排除它,只需将其移到括号外),以及第二个子模式中的原因(不带引号,将它们移到括号内以包含它们)。

于 2012-12-30T22:47:04.883 回答
1

正如我在评论中提到的,我使用最小的解析器完成了类似的任务。这是 CoffeeScript 中的一个,它编译为 JavaScript:

parse = (input) ->
  index = 0
  peek = -> input.charAt index
  advance = -> ++index; peek()
  advanceRP = ->
    last = peek()
    advance()
    return last
  collect = (regex) -> (advanceRP() while peek().match regex).join ''
  skipWhiteSpace = -> collect /\s/
  literal = ->
    result = collect /[@\w]/
    skipWhiteSpace()
    return result
  string = ->
    if peek() == '"'
      advance()
      result = []
      loop
        result.push collect /[^"]/
        advance()  # skip past closing quote
        if peek() is '"'  # and therefore an escape (double quote)
          result.push '"'
        else if peek().match /\s?/
          break  # whitespace or end of input; end of string
        else
          # neither another quote nor whitespace;
          # they probably forgot to escape the quote.
          # be lenient, here.
          result.push '"'
      skipWhiteSpace()
      result.join ''
    else
      literal()

  return error: 'does not start with slash' if peek() isnt '/'
  advance()
  command = literal()
  return error: 'command unrecognized' if command isnt 'ban'
  person = string()
  if peek() == '"'
    reason = string()
    return error: 'junk after end of command' if index < input.length
  else
    reason = input.substring index

  command: 'ban'
  person: person
  reason: reason

试试看:

coffee> parse '/ban @person reason'
{ command: 'ban', person: '@person', reason: 'reason' }
coffee> parse '/ban "@person with ""escaped"" quotes" and the reason doesn\'t need "quotes"'
{ command: 'ban'
, person: '@person with "escaped" quotes'
, reason: 'and the reason doesn\'t even need "quotes"'
}
于 2012-12-30T23:21:44.650 回答