Pergunta

Eu tenho uma consulta request-uri na forma de "/ node / 143" (apenas um exemplo do formato).

Eu quero tirar a primeira barra da corda, eu olhei para a função Remover e teve uma tentativa. Eu simplesmente não consigo fazê-lo funcionar (estou usando SBCL no Linux).

Eu configurei o pedido-URI usando este código.

(setq request-uri "/node/143")

Quando eu verificar a variável eu tenho esta retornado.

request-uri
"/node/143"

Agora tente remover a primeira barra (neste momento é apenas alguma coisa para ver como a função é usada adequadamente).

(remove "/" request-uri)
"/node/143"

(remove '/ request-uri)
"/node/143"

Eu até tentei fornecer uma lista

(remove '("/") request-uri)
"/node/143"

(remove '('/) request-uri)
"/node/143"

Apesar de cordas são vetores de caracteres Eu pensei que de alguma forma talvez a seqüência inteira pode ser colocado em uma célula e eu tentei remover a coisa toda, ainda não sorte.

(remove "/node/143" request-uri)
"/node/143"

(remove '/node143 request-uri)
"/node/143"

Então, eu estou em uma perda agora, essa função aparentemente simples tem realmente me iludiu, pensei eu segui a documentação ao pé da letra, mas nada está funcionando.

Alguém pode lançar alguma luz sobre o que está acontecendo aqui?

Graças.

Editar:. Eu encontrei a resposta à minha pergunta, o que levantou uma outra questão

Para remover um elemento da corda que eu usei

(remove #\/ request-uri)

E sobre toda uma série

`(remove #\node request-uri`)

Só funciona para o primeiro caractere e lança um erro, ea seguinte tudo não fazer nada.

(remove "node" request-uri)
(remove 'node request-uri)
(remove ?\node request-uri)
(remove #\node request-uri)
(remove '("node") request-uri)

Eu não tenho certeza de que outra forma ele deve ser abordado aqui.

Foi útil?

Solução

Aprenda a ler o Common Lisp HyperSpec .

Seqüências , Arrays (vetores unidimensionais de caracteres) e, assim, Cordas . Isto significa que a maioria dessas funções são aplicáveis.

Vamos olhar REMOVE . CLHS dá esta assinatura:

remove item sequence &key from-end test test-not start end count key
    => result-sequence

Strings são sequências de caracteres. Assim, uma chamada para remover seria:

(remove #\/ "/foo/")

ou (por exemplo)

(remove #\/ "/foo/" :start 2)

Lembre-se: # \ a é um personagem. # \ Nó é nenhum personagem. Ilegal. Uma string é "/ foo /".

O item para remover de uma corda tem que ser um personagem. Nada mais. Por quê? Como o teste é pelo EQL padrão e EQL compara o caractere na seqüência com o seu argumento item. Também fundamental é pela identidade padrão e não alterar os itens.

E se o seu argumento é uma string? Bem, então você tem que fazer mais:

 (remove "/" "/abc/" :key #'string :test #'equal)

Isto olha cada personagem da seqüência e torna-lo em uma corda. A seqüência de caracteres, em seguida, serão comparados com seu artigo "/" usando a função EQUAL. Isso funciona também. O custo é de que ele precisa para gerar uma seqüência de cada caráter de "/ abc /", cada corda é um objeto novo.

Outra maneira de fazer isso é:

 (remove "/" "/abc/" :test (lambda (a b) (eql (aref a 0) b)))

Acima recupera o primeiro caractere "/" em cada teste e compara-o com a personagem da string "/ abc /". Mais uma vez o custo é que ele precisa para obter o personagem cinco vezes (neste exemplo).

Portanto, a melhor maneira de escrevê-lo se o seu objeto original vem como uma string:

(remove (aref "/" 0) "/abc/")

Acima temos a personagem da string "/" uma vez e depois remover compara esse personagem com o teste EQL padrão com cada caractere na string - ele retorna uma nova seqüência daqueles personagens que não são EQL a # / <. / p>

O que você espera? \ Foo para ser? Em Common Lisp este é o símbolo |? Foo |.

Além disso (remover "foo" "afoob") não funciona desde que uma string ( "foo" aqui) não é um elemento de uma cadeia. Lembre-se, os personagens são elementos de cordas. Lembre-se também que as cordas com um item como "/" ainda são cordas e não um personagem. Assim, "/" e # / são de tipo diferente. O primeiro é uma string eo segundo é um personagem.

subseq extrai uma sequência a partir de uma sequência. Isso significa que também extrai uma seqüência de outra string:

(subseq "0123456" 1 5)
     where 1 is the start and 5 is the end index.

CONCATENATE acrescenta seqüências. Isso significa que ele também anexa strings.

(concatenate 'string "abc" "123")
  returns a new string with the strings "abc" and "123" appended.

Para remover partes de uma seqüência de ver também as funções String-Trim, String-LEFT-Trim e STRING-RIGHT-Trim.

Assim, como em uma outra resposta para remover substrings de uma string, você precisa escrever algum código para extrair algumas cordas e então concatenar os.

pesquisa Pesquisas para strings em strings.

Outras dicas

Para remover uma substring inteira, você terá que fazer uma nova função, por exemplo:.

(defun remove-string (rem-string full-string &key from-end (test #'eql)
                      test-not (start1 0) end1 (start2 0) end2 key)
  "returns full-string with rem-string removed"
  (let ((subst-point (search rem-string full-string 
                             :from-end from-end
                             :test test :test-not test-not
                             :start1 start1 :end1 end1
                             :start2 start2 :end2 end2 :key key)))
    (if subst-point
        (concatenate 'string
                     (subseq full-string 0 subst-point)
                     (subseq full-string (+ subst-point (length rem-string))))
        full-string)))

Este é apenas um ponto de partida. Eu replicado todas as opções para a pesquisa, mas acho que algumas opções não fazem sentido neste contexto. Pelo menos isso funciona:

(remove-string "node" "this is a node or not")

Para casos mais elaborados, talvez você deve dar uma olhada em cl-ppcre, uma biblioteca regex.

Explicação:

(remove "node" request-uri)
(remove 'node request-uri)
(remove ?\node request-uri)
(remove #\node request-uri)
(remove '("node") request-uri)

Estes são (respectivamente): uma corda, um (citado) símbolo, um (avaliado) símbolo, um literal de caracteres malformada, e uma lista contendo uma string. remove um objecto a partir de um objecto de sequcia-, e um cadeia não é uma sequência de qualquer uma dessas coisas.

Se você quiser apenas para remover parte da cadeia de caracteres, subseq pode fazer o truque:

(let ((uri "/node/143"))
  (when (string= (subseq uri 0 6) "/node/")
    (format t "user wants node ~D" (parse-integer (subseq uri 6)))))

Para que as coisas mais complexas, você provavelmente vai querer uma biblioteca como cl-ppcre e / ou split-sequência. (Se você estiver usando Hunchentoot, você já tem o ex-carregado.)

Esta falha porque "/" é uma string, não um personagem.

(remove "/" request-uri)
"/node/143"

Se quiser que o personagem, você precisa usar # / ou seja, o caractere de barra.

(remove #\/ request-uri)
"node143"

Mas como você pode ver, ele vai remover todas barras. De acordo com a página doc é ligada, retire leva uma palavra-chave param chamado: contagem, que diz quantos itens para remover. Então, você poderia fazer isso.

(remove #\/ request-uri :count 1)
"node/143"

Espero que isso ajude.

:: EDIT ::

Não é? /, É # /. Graças Douglas!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top