| Bytes | Lang | Time | Link |
|---|---|---|---|
| 076 | AWK | 250414T175804Z | xrs |
| 056 | Vyxal | 220209T222217Z | Seggan |
| 181 | C gcc | 220208T043644Z | veqtrus |
| 074 | Burlesque no RegEx | 220208T001333Z | DeathInc |
| 051 | Retina 0.8.2 | 220207T161627Z | Neil |
| 064 | JavaScript Node.js | 220207T163514Z | nununois |
| 171 | Python | 220207T142931Z | Ginger |
| 132 | JavaScript Node.js | 220207T162847Z | ophact |
| 052 | Charcoal | 220207T162807Z | Neil |
| 036 | 05AB1E | 220207T152053Z | Kevin Cr |
AWK, 76 bytes
1,$0=gsub(/(\..*){4}|[A-Z]\S*[A-Z]|[^a-zA-Z0-9\-_\.,?! ]|[!?].*[!?]|,.*,/,X)
Similar to other regex responses, though I'm not super confident in my regex-fu.
Vyxal, 62 58 57 56 bytes
`[^\w.,?! -]`ẎL‛?!øB?ẎL1>?⌈ƛ`[A-Z]`nẎL1>;a?\.O3>?\,O1>Wa
My first Vyxal answer, and I'm loving this language. So much more intuitive than Jelly. 99% sure this can be golfed more.
Explanation:
`[^\w.,?! -]`?ẎL‛?!øB?ẎL1>?⌈ƛ`[A-Z]`nẎL1>;a?\.O3>?\,O1>Wa ; Takes the word as input
`[^\w.,?! -]`ẎL ; Length of any matched of illegal characters (0 if no matches)
‛?! ; The string '?!'
øB ; Bracketify: converts '?!' to '[?!]'
?ẎL ; Find all '?' and '!' and count them
1> ; More than 1?
?⌈ ; Split the input on spaces
ƛ ; ; Mapping lambda: maps all the words using the following criteria
`[A-Z]`nẎL ; How many capital letters in the word?
1> ; More than 1?
a ; Any truthy? (i.e. any words with more than 1 capital letter?)
?\.O ; Count full stops in string
3> ; More than 3?
?\,O ; Count commas in string
1> ; More than 1?
W ; Turn the stack into a list
a ; Any truthy? (i.e. are any of the conditions true?)
Vyxal, 56 bytes
`[^\w-.,?! ]|[A-Z]\S*[A-Z]|[!?].*[!?]|,.*,|(\..*){4}`?ẎL
A different version based off of the regex Node.js answer
C (gcc), 251 219 215 199 197 193 189 184 181 bytes
-32 bytes thanks to @ceilingcat
-4 bytes by subtracting 43 from c
-16 bytes by moving comparisons inside ternaries
-2 bytes by removing unneeded brackets
-4 bytes by realising that ++x>1 is equivalent to x++
-4 bytes by rearranging outer ternary and adjusting subtracted amount
-5 bytes by moving checks inside loop condition
-3 bytes by using the n array for storing the output.
#define C(l,h)c>l&c<h?n[l]++
f(char*s){int c,n[64]={1};while((c=*s++)&&!(c-=41,c+9?*n=c+8&&c-22?C(55,82)<0:C(23,50):C(6,17)<0:C(4,6)>2:C(2,4):c-4&&c-54:n[1]++:(n[23]=0)));return*n;}
The C macro increments a counter for a character class. I used decimal literals instead of char literals. When a space is encountered the uppercase counter is reset.
Burlesque (no RegEx), 103 88 81 76 74 bytes
Jwd{qsnfl2.<}aljJbc".,?!"qCNZ]^p.+1<=j1<=&&j3<=&&jNBqrifn" -_.,?!"\\z?&&&&
Almost certainly a shorter answer possible. This is pretty brute force.
Jwd{qsnfl2.<}alj # Check double caps
J # Duplicate input
wd # Split into words
{
qsn # isUpper
fl # filter length
2.< # <2
} #
al # All
j # Swap input to top of stack
Jbc".,?!"qCNZ]^p.+1<=j1<=&&j3<=&&j # Check char counts
J # Duplicate input
bc # Box and repeat infinitely
".,?!" # String
qCN # Count occurences
Z] # Zip with count (return list of counts for each)
^p # Push list to stack
.+ # Add ?s and !s
1<=j # ?+! <= 1
1<=&&j # , <= 1
3<=&& # . <= 3
NBqrifn" -_.,?!"\\z? # Check valid chars
NB # Remove duplicates
qri # Quoted is alphanum
fn # Filter not
" -_.,?!" # Valid non-letter
\\ # List diff
z? # Empty
&&&& # Reduce all 3 by ands
Retina 0.8.2, 55 53 51 bytes
[^-.,?!\w ]|[?!].*[?!]|,.*,|(\..*){4}|[A-Z]\S*[A-Z]
Try it online! Link includes test cases. Edit: Saved 2 bytes thanks to @Ausername and another 2 bytes thanks to @nununoisy. Simply reports on the number of banned patterns it finds, so for some spam the truthy value might be greater than 1; if this is undesirable, 1` can be prefixed to the program which limits the count to 1. Explanation:
[^-.,?!\w ] Check for illegal characters.
[?!].*[?!] Check for two question or exclamation marks.
,.*, Check for two commas.
(\..*){4} Check for four or more full stops.
[A-Z]\S*[A-Z] Check for two uppercase letters in the same word.
JavaScript (Node.js), 72 71 68 64 bytes
-1 byte thanks to @ThisFieldIsRequired
-3 bytes inspired by @Neil's Retina answer
-2 bytes thanks to @emanresuA (see @Neil's answer)
-2 bytes by modifying final test slightly
m=>/[^\w-.,?! ]|[A-Z]\S*[A-Z]|[!?].*[!?]|,.*,|(\..*){4}/.test(m)
Regex abuse FTW.
Here's how it works:
[^\w-.,?! ]matches any character that isn't allowed.[A-Z]\S*[A-Z]matches two uppercase letters without a space in between, i.e. two capitals in a single word[!?].*[!?]matches two exclamation/question marks with anything in between,.*,matches two commas with anything in between(\..*){4}matches four periods with anything in between
If you put these together in a single regex as alternates, you get a spam filter that matches all criteria.
Python, 177 171 bytes
This requires the re module, so that adds an additional 9 bytes.
lambda i:any([re.search('[^a-zA-Z0-9\-.\,\?\! ]',i),*[len(re.findall("[A-Z]",w))>1for w in i.split(" ")],len(re.findall('[?!]'))>1,i.count(".")>3,i.count(",")>1])
JavaScript (Node.js), 132 bytes
n=>n.split` `.some(w=>/[^\w-.,?!]/.test(w)+(F=C=>w.split(C).length-1,c+=F`.`,d+=F(/[?!]/),e+=F`,`,F(/[A-Z]/)>1),c=d=e=0)|c>3|d>1|e>1
If you want to be completely sure that the answer works, add a backslash before the dash in the first regular expression. The code above passes all test cases, but a comment on the python answer seems to indicate that there should be a backslash or space before the dash. If anyone could confirm or disprove the statement above, it would be very helpful.
Charcoal, 52 bytes
⌈⟦⊙θ¬№⁺ !,-.?_⭆⁶²⍘λφι‹¹⁺№θ!№θ?‹¹№θ,‹³№θ.⊙⪪θ ‹¹LΦι№αλ
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - for spam, nothing if not. Explanation:
⌈⟦
Output if any of the following is true.
⊙θ¬№⁺ !,-.?_⭆⁶²⍘λφι
Check whether any characters aren't contained in the permitted list including the 62 alphanumeric characters used by default for base conversion.
‹¹⁺№θ!№θ?
Check whether there is more than one exclamation or question mark.
‹¹№θ,
Check whether there is more than one comma.
‹³№θ.
Check whether there are more than three full stops.
⊙⪪θ ‹¹LΦι№αλ
Check whether any word has more than one upper case letter.
05AB1E, 38 37 36 bytes
žj…,!?©… -.JÃÊ·IS#.uOI®S¢ā£OI'.¢;M2@
Try it online or verify all test cases.
Explanation:
žj # "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
…,!? # Push string ",!?"
© # Store it in variable `®` (without popping)
… -. # Push string " -."
J # Join all three strings on the stack together
à # Only keep those characters from the (implicit) input
Ê # Check if it's now NOT equal to the (implicit) input
· # Double it (2 if truthy; 0 if falsey)
I # Push the input
S # Convert it to a list of characters
# # Split it on spaces
.u # Check for each character if it's an uppercased letter
O # Sum those checks for each word
®S # Push [",","!","?"] (variable `®` as list of characters)
I ¢ # Count these characters in the input
ā # Push a list in the range [1,length] (without popping): [1,2,3]
£ # Split the counts into those parts: [[a],[b,c],[]]
# (a=count of ","; b=count of "!"; c=count of "?")
O # Sum each inner list: [a,b+c,0]
I # Push the input yet again
'.¢ '# Count the amount of "." in the input
; # Halve it
M # Push the largest number of the stack (including within lists)
2@ # Check if this max is ≥2
# (after which it is output implicitly as result)