#Hashtag_or_not

25

Neste desafio de código de golfe, você verificará hashtags!

#What_your_code_should_do

Entrada é uma sequência. Emita um valor verdadeiro se for uma hashtag válida e, caso contrário, um valor falso.

Definimos uma string como um Hashtag válido se ...

  • Começa com um hash ( #).
  • Ele não tem um número logo após a hashtag (por exemplo, #2016USElectionnão é uma hashtag válida).
  • Não possui "caracteres especiais" (ou seja, qualquer caractere que não seja um alfabeto, sublinhado ( _) ou número).

Você pode assumir que a entrada contém apenas caracteres ASCII. (Seria injusto se fizéssemos o Unicode também.)

#Regras

Aplicam-se regras básicas .

#Exemplos

Verdade:

#
#e
#_ABC 
#thisisanunexpectedlylongstringxoxoxoxo
#USElection2016

Falsy:

Hello, World!
#12thBday
#not-valid
#alsoNotValid!
#!not_a_hash
Laikoni
fonte
10
É #realmente uma hashtag válida?
Adám 18/07/16
4
É #öäüválido?
Chrki
7
#não é uma hashtag válida por nenhum sistema, Facebook ou Twitter, ele também quebra as regras definidas, também não tenho certeza de que #_ABC é válido novamente nelas, mas não tenho certeza disso.
Martin Barker
3
Presumo que an alphabetsignifica ascii letra maiúscula ou minúscula? ie abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?
Rɪᴋᴇʀ
7
Um # não é uma hashtag. É um hash. É seguido por uma cadeia de caracteres o que as redes de mídia social chamam de hashtag. É uma tag, que começa com um hash.
I-CONICA

Respostas:

19

Retina , 12 bytes

^#(?!\d)\w*$

Imprime 1para hashtags e 0outros.

Experimente online! (A primeira linha ativa um conjunto de testes separado por avanço de linha.)

Não há muito a explicar aqui, esta é uma implementação literal da definição: ^e $são apenas âncoras, garantindo que a correspondência cubra toda a cadeia, #verifique se a cadeia começa com a #, (?!\d)garante que o próximo caractere não seja um dígito (sem avançar posição do mecanismo regex), \w*verifica se podemos chegar ao final da string com zero ou mais letras, dígitos ou sublinhados.

Por padrão, a Retina conta o número de correspondências do regex especificado, e é por isso que isso fornece 1tags hash válidas e 0outras coisas.

Martin Ender
fonte
Em Perl, (?!\d)é (?=\D)... mas eu não sei como você escreveu Retina. É possível usar (?\D)sem o =e salvar um byte? (Se não, vale a pena editar o idioma de modo que é factível?)
msh210
2
@ msh210 (?!\d)é diferente (?=\D), pois o último requer algum caractere após a posição atual, enquanto o primeiro está satisfeito com o final da string. Independentemente disso, atualmente não é possível ajustar o sabor do regex (já que estou apenas entregando o regex ao mecanismo de regex do .NET), mas fazer essas alterações está no roteiro em algum lugar (muito distante) abaixo da linha.
Martin Ender
1
Dito isto, acho que não tornarei o =opcional. A (?...)sintaxe inteira foi escolhida para a extensibilidade, pois o personagem após o ?nunca é opcional e determina que tipo de grupo é esse, e eu acho que não quero desistir dessa extensibilidade.
Martin Ender
(re seu primeiro comentário) Duh, é claro, eu deveria ter notado isso. Mas é irrelevante para esta resposta. (re seu segundo) Sim, faz sentido. Não é, afinal, também (?{e (??e (?<(tanto para a captura de grupos e para lookbehind) e (?-e (?1e, claro, o básico (?:. E talvez alguns que eu tenha perdido.
Msh210
6

Perl, 22 bytes

Código de 21 bytes +1 para -p

$_=/^#([a-z_]\w*)?$/i

Imprime 1 se for uma hashtag válida. Seqüência vazia, caso contrário.

Uso

perl -pe '$_=/^#([a-z_]\w*)?$/i' <<< '#'
1
perl -pe '$_=/^#([a-z_]\w*)?$/i' <<< '#_test'
1
perl -pe '$_=/^#([a-z_]\w*)?$/i' <<< '#1test'

Economizou 2 bytes graças a Martin Ender (e outros 4 usando seu método de busca )


Perl, 18 bytes

Código de 17 bytes +1 para -p

Usando o lookaround de Martin, isso pode ser muito mais curto!

$_=/^#(?!\d)\w*$/
Dom Hastings
fonte
Você copiou o de Martin e o editou, certo?
@MatthewRoh A segunda resposta usa o mecanismo de Martin sim. Ele disse que eu poderia usá-lo, mas eu não queria que fosse a minha resposta principal, pois eu não a criei! Eu adicionei para comparação. Retina ainda vence Perl facilmente neste tipo de desafio!
Dom Hastings
6

JavaScript (ES6), 25 bytes

s=>/^#(?!\d)\w*$/.test(s)

F = s => /^#(?!\d)\w*$/.test(s)
input.oninput = () => result.innerHTML = input.value ? F(input.value) ? '\ud83d\udc8e' : '\ud83d\udca9' : '\ud83d\udcad';
#input, #result {
  vertical-align: middle;
  display: inline-block;
}
#input {
  line-height: 2em;
}
#result {
    font-size: 2em;
}
<input id="input" type="text"/> <span id="result">&#x1f4ad</span>

George Reith
fonte
5

C, 80 bytes

A função f()pega a string como argumento e modifica int *bpara 1 ou 0 para indicar verdade / falsidade.

f(char*p,int*b){for(*b=(*p==35)&&!isdigit(p[1]);*p;++p)*b&=isalnum(*p)||*p==95;}

Se a string sempre tiver pelo menos um caractere (ou seja, nunca uma string vazia), um byte poderá ser cortado por 79 bytes:

f(char*p,int*b){for(*b=(*p==35)&&!isdigit(p[1]);*++p;)*b&=isalnum(*p)||*p==95;}
owacoder
fonte
5

Python 3, 41 bytes

import re
re.compile('#(?!\d)\w*$').match
Gábor Fekete
fonte
Isso deve estar absolutamente bem. Como os objetos de correspondência são verdadeiros e Nonefalsos, acho que deixar bool()tudo bem.
19416 Lynn
Sim, eu pensei sobre isso, obrigado por esclarecer isso!
Gábor Fekete
Isso gera um valor verdadeiro para "#fix me Gábor" também. BTW, vejo que as regras também estão sendo ignoradas por outras pessoas, mas isso costumava ser considerado um trecho, que geralmente não é aceito como resposta, a menos que a pergunta permita explicitamente.
manatwork 19/07/16
Obrigado, eu o reescrevi para lidar com o caso que você escreveu e o transformou em uma função lambda.
Gábor Fekete
2
Que tal re.compile('#(?!\d)\w*$').match? É aceitável descartar o f=BTW.
Lynn
4

Braquilog , 55 bytes

"#"|h"#",?b@lL'(eE,@A:"1234567890":"_"c'eE),@A:"_"ce~hL

Isso não usa regex.

Explicação

Main predicate, Input (?) is a string

  "#"                           ? = "#"
|                             Or
  h"#",                         First character of ? is "#"
  ?b@lL                         L is the rest of the chars of ? lowercased
  '(                            It is not possible for any char of L that...
    eE,                           Call this char E
    @A:"1234567890":"_"c          Concatenate the lowercase alphabet with the digits and "_"
    'eE                           E is not a member of that concatenated string
   ),                           
   @A:"_"c                      Concatenate the lowercase alphabet with "_"
   e~hL                         One char of that concatenated string is the first char of L
Fatalizar
fonte
4

Python 3, 103 93 bytes

all((c=='_'or c.isalpha()*i>0)^(i<1and'#'==c)^(c.isdigit()*i>1)for i,c in enumerate(input()))

O #ser Trueme matou aqui, eu tinha para enumerar a corda para evitar um erro índice na entrada de caracteres única.

atlasologist
fonte
1
+1. Agradável! Eu esqueci completamente o isalpha()método na minha resposta py3: D "#" sendo verdadeiro, também me destruiu.
Yytsi 18/07/2016
4

PowerShell v2 +, 25 bytes

$args-match'^#(?!\d)\w*$'

Usando a expressão regular de Martin , envolvida apenas no -matchoperador do PowerShell, juntamente com a entrada $args. Para valores truthy / falsey, isso retornará a própria string em uma correspondência (um valor de verdade) ou nada em uma não correspondência (um valor de falsey). Isso ocorre porque quando um operador de comparação é aplicado a uma matriz, ele retorna qualquer coisa que satisfaça esse operador.

Alguns exemplos (agrupados [bool]para tornar a saída mais clara):

PS C:\Tools\Scripts\golfing> [bool](.\hashtag-or-not.ps1 '#2016Election')
False

PS C:\Tools\Scripts\golfing> [bool](.\hashtag-or-not.ps1 'Hello, World!')
False

PS C:\Tools\Scripts\golfing> [bool](.\hashtag-or-not.ps1 '#')
True

PS C:\Tools\Scripts\golfing> [bool](.\hashtag-or-not.ps1 '')
False

PS C:\Tools\Scripts\golfing> [bool](.\hashtag-or-not.ps1 '#USElection2016')
True
AdmBorkBork
fonte
3

Mathematica, 52 46 43 bytes

Salvo 6 9 bytes devido a @MartinEnder .

StringMatchQ@RegularExpression@"#(?!\d)\w*"

Função. Pega uma string como entrada e retorna Trueou Falsecomo saída. Muito simples, apenas combina com o regex /#(?!\d)\w*/.

LegionMammal978
fonte
Eu tenho motivos para acreditar que isso não funcionará para entradas como, hello#worlduma vez que você não tem as âncoras de sequência de início e fim. Eu não conheço o Mathematica, então não tenho certeza.
Value Ink
Tudo certo, eu posso viver com isso. Tenha seu +1
Value Ink
3

Dyalog APL , 22 20 bytes

Sem RegEx:

{0≤⎕NC 1↓⍵,⎕A}∧'#'=⊃

-2 graças a ngn

Adão
fonte
1
Uau. Ainda existem pessoas que conhecem APL. Faz 37 anos desde que eu o usei!
Auspex
O @Auspex APL está bem, mas poucos recursos foram adicionados nesses anos.
Adám 19/07/19
3

Python 2, 79 bytes

lambda x:x=='#'or(1>x[1].isdigit())&x[1:].replace('_','').isalnum()&('#'==x[0])

Primeira tentativa de golfe. Versão não destruída:

def f(x):
    if x == '#':
        return True
    else:
        return x[0]=='#' and x[1:].replace('_','').isalnum() and not x[1].isdigit()
Cowabunghole
fonte
Boa resposta e bem-vindo ao site!
DJMcMayhem
3

Oitava, 37 56 54 43 bytes

Obrigado a @LuisMendo por remover 8 bytes!

@(s)s(1)==35&(isvarname(s(2:end))|nnz(s)<2)

Não é muito golfista, mas muito embutido.
Editar: o código original aceita cadeias sem '#' à esquerda. Acho que deveria ter ficado com o regex.

Conjunto de testes em ideone .

taça
fonte
3

Python3 - 156 128 bytes

lambda n:n=="#"or(n[0]=="#")*all(any([47<ord(c)<58,64<ord(c)<91,ord(c)==95,96<ord(c)<123])for c in n[1:]+"0")*~(47<ord(n[1])<58)

Uma solução que não usa regex. 0 é falsey e todos os outros valores são verdadeiros.

Obrigado a @LeakyNun por salvar bytes!

Yytsi
fonte
@LeakyNun Eu tive que remover o +0depois n[1:], mas, infelizmente, ainda não funcionou: / Deu falso para "#d".
Yytsi 18/07/2016
@LeakyNun ainda não funciona :( Mais uma vez, tivemos que remover +0mas falha em "# d" Eu testei no Python3 embora Não tenho certeza se ele vai trabalhar em python2..
Yytsi
@LeakyNun Simplesmente falso.
Yytsi 18/07/2016
@LeakyNun Lança IndexOutOfRangepara "#" e Falsepara "#d".
Yytsi 18/07/2016
lambda n:n=="#"or(n[0]=="#")*all(any([47<ord(c)<58,64<ord(c)<91,ord(c)==95,96<ord(c)<123])for c in n[1:]+"0")*~(47<ord(n[1])<58)para 128 bytes. Prova de que funciona #
Leaky Nun
2

Lua, 59 55 54 bytes

Código

s=arg[1]print(load(s:sub(2).."=0")and s:sub(1,1)=="#")

Como funciona:

  1. Verifique se o restante dos caracteres pode ser um identificador valud de Lua (os identificadores em Lua seguem as mesmas regras que as hashtags.)
  2. Verifique se o primeiro caractere é a #.

Recebe entrada da linha de comando. Imprime truese a string for uma hashtag válida, caso contrário, ela será impressa nil.

xaxa
fonte
2

Planilhas Google, 30 bytes

Uma função de planilha anônima que recebe entrada da célula A1a compara com a expressão RE2 e gera o resultado para a célula que está chamando.

=RegexMatch(A1,"^#([a-z_]\w*)?
Taylor Scott
fonte
1

05AB1E , 18 bytes

Código:

¬'#Qs¦A«¬d_sDžjKQP

Usa a codificação CP-1252 . Experimente online! .

Adnan
fonte
1

Sed 19 + 2 = 21 bytes

/^#([a-z_]\w*)?$/Ip

Isso filtra todas as não hashtags e gera hashtags válidas.

Executar como sed -rn "/^#$|^#[a-z]\w*$/Ip". Saia com Ctrl+ D(envie EOF).

someonewithpc
fonte
1

GNU grep, 15 + 2 = 17 bytes

grep -Ei '^#([a-z_]\w*)?$'

Teste:

$ echo '#
#e
#_ABC
#thisisanunexpectedlylongstringxoxoxoxo
#USElection2016
Hello, World!
#12thBday
#not-valid
#alsoNotValid!' | grep -Ei '^#([a-z_][a-z0-9_]*)?$'

Saída:

#
#e
#_ABC
#thisisanunexpectedlylongstringxoxoxoxo
#USElection2016
Jordânia
fonte
1

Python 3, 97 bytes 70 bytes 56 bytes

lambda x:s=x[2:];b=x[1];all(x!="#",[x[0]=="#",any[b.isalpha(),"_"in b],any[s.isalnum(),"_"in s]])

(Código alterado) legível por humanos

x=input()
if x[0]=="#" and x[1].isalpha() and str(x)[2:].isalnum():
    print(True)
else:
    print(False)

Dignissimus - Spammy
fonte
Boa resposta e bem-vindo ao site! As funções também são permitidos, assim que você poderia encurtar este um pouco comlambda x:all(True==[x[0]=="#",x[1].isalpha(),x[2:].isalpha()])
DJMcMayhem
Não tem problema, estou feliz por poder ajudar!
DJMcMayhem
1
Eu odeio ser o portador de más notícias, mas isso não falha em '#' , que o OP diz ser verdade? Também não falhará se a hashtag contiver sublinhados falsos isalpha?
TheBikingViking
@TheBikingViking desculpe, vou tentar consertar isso agora
Dignissimus # Spammy
2
@TheBikingViking Não é isso que não significa competição. Não competir não é desculpa para um envio inválido. O procedimento correto é excluir a resposta, corrigi-la e desfazer a exclusão.
Mego
1

Pyke, 19 bytes

\#.^It,!It\_D-PRkq|

Experimente aqui!

Solução rápida para hoje à noite

Azul
fonte
1
@kenorb reiniciado-lo, de ping-me se houver mais problemas
azuis
#123retorna ainda nada, não deve retornar 0?
Kenorb 18/07
1
Nada é uma falsa boolean
Azul
1

Ruby, 16 + 3 1 ( nsinalizador) = 19 17 bytes

Usa 0como verdade e nilcomo falsidade.

p~/^#(?!\d)\w*$/

Execute-o como ruby -ne 'p~/^#(?!\d)\w*$/'. Obrigado a @manatwork por corrigir o erro do bash ao executar o programa.

Value Ink
fonte
1
Faça um favor a si mesmo e sempre coloque o código entre aspas simples. Caso contrário, o shell tentará (ou, pior ainda, executar com êxito) todo tipo de expansão. (Quanto à questão atual com !, consulte designadores de evento no homem bash.)
manatwork
1

ML padrão , 121 118 107 bytes

(fn#"#"::a=>(fn x::r=>x> #"@"andalso List.all(fn#"_"=>1=1|c=>Char.isAlphaNum c)a|e=>1=1)a|e=>1=0)o explode;

Experimente online! Solução funcional sem usar regex. Declara uma função anônima que está vinculada ao identificador implícito de resultados it.

> val it = fn : string -> bool    
- it "#valid_hash";
> val it = true : bool
Laikoni
fonte
4
isAlphaNum$orelseisso é um pouco ameaçador ... #
cat
@cat, pode ser a única coisa positiva que se pode dizer sobre operadores booleanos detalhados como orelsee andalso.
Laikoni
2
É como AlphaNum, orelse!! ( orelse what?)
cat
Pode-se considerar o o explodeno final para ser bastante ameaçador também ...
Laikoni
1
SML parece muito assustador, eu não acho que eu poderia lidar com isso durante todo o dia: c
cat
1

Excel VBA, 54 bytes

Função de janela imediata VBE anônima que recebe entrada da célula [A1], verifica se o valor da célula corresponde ao Likepadrão e gera saída Booleanpara a janela imediata VBE

?Not[Left(A1,2)]Like"[#]#"And[A1]Like"[#][_a-zA-z0-9]*
Taylor Scott
fonte
0

C #, 92 bytes

s=>s[0]=='#'&s.Length>1&&(s[1]<48|s[1]>57)&s.Skip(1).All(x=>char.IsLetterOrDigit(x)|x=='_');

C # lambda ( Predicate) onde entrada é a stringe saída é a bool.

Experimente online!

aloisdg diz Restabelecer Monica
fonte
0

Lua, 39 bytes

print(arg[1]:match("^#[%a_][%a_%d]*$"))

Copypasta simples da descrição da partida. Saídas falsas, nilse não hashtag, retornam verdadeiramente a hashtag.

Pode ser reduzido para mais um byte usando findse a lista de saída de dois valores (que é verdadeira) não quebra as regras.

Oleg V. Volkov
fonte
Eu acho que isso não corresponde a um #por si só.
Martin Ender
@MartinEnder, é claro. Não deveria. Nenhuma das principais respostas faz isso também. Também codegolf.stackexchange.com/questions/85619/hashtag-or-not/…
Oleg V. Volkov
Se #é uma hashtag no Twitter ou no Facebook, é irrelevante para esse desafio. A especificação é muito clara no fato de que #deve ser considerada uma hashtag para os propósitos deste desafio. E enquanto eu não tenho verificado todas as respostas, tudo o que fiz de verificação não aceitar #como uma hashtag, então eu não tenho certeza que as respostas top você está se referindo.
Martin Ender
0

Clojure, 130 135 132 bytes

  • +5 bytes para lidar com um NPE que ocorreu quando a sequência consistia em apenas uma hashtag.

  • -2 bytes usando Character/isLetterOrDigit.

(fn[s](let[[h & r]s n(map int r)](and(= h\#)(not(<= 48(or(first n)0)57))(every? #(or(Character/isLetterOrDigit^long %)(= 95 %))n))))

Ungolfed:

(defn hashtag? [s]
  (let [[h & r] s
        codes (map int r)]
    (and (= h \#)
         (not (<= 48 (or (first codes) 0) 57))
         (every?
           #(or (Character/isLetterOrDigit ^long %)
                (= 95 %))
           codes))))
Carcinigenicado
fonte
Opa, isso realmente fornece um NPE para "#". Me dê um segundo.
Carcigenicate