HE COMETH NOT - a zalgo challenge [duplicate]

Write a program or function that, given a string, will strip it of zalgo, if any exists.

Zalgo

For this post, zalgo is defined as any character from the following Unicode ranges:

• Combining Diacritical Marks (0300–036F)
• Combining Diacritical Marks Extended (1AB0–1AFF)
• Combining Diacritical Marks Supplement (1DC0–1DFF)
• Combining Diacritical Marks for Symbols (20D0–20FF)
• Combining Half Marks (FE20–FE2F)

https://en.wikipedia.org/wiki/Combining_character#Unicode_ranges

Input

• May be passed via command line arguments, STDIN, or any other standard method of input supported by your language
• Will be a string that may or may not contain zalgo or other non-ASCII characters

Output

Output should be a string that does not contain any zalgo.

Test Cases

Input -> Output

HE̸͚ͦ ̓C͉Õ̗͕M͙͌͆E̋̃ͥT̠͕͌H̤̯͛ -> HE COMETH
C͉̊od̓e͔͝ ̆G̀̑ͧo͜l͔̯͊f͉͍ -> Code Golf
aaaͧͩa͕̰ȃ̘͕aa̚͢͝aa͗̿͢ -> aaaaaaaaa
ññ        -> ñn
⚡⃤       -> ⚡


Scoring

As this is , shortest answer in bytes wins.

• Is the string guaranteed to only contain ASCII and/or Zalgo? Or may it contain other unicode? May 6, 2017 at 19:00
• What about legitimate uses of those characters? Zalgo is pretty much only when those characters stack with each other in a way that was never intended. May 6, 2017 at 19:16
• @DJMcMayhem The input string may have other non-ASCII characters that must not be removed. May 6, 2017 at 19:16
• @totallyhuman I was thinking a more generic approach: only stripping if more than one occurs after a "standard" character. That is a͕ is fine but a͕̰ gets stripped to a. (Also now, thanks to the emoji detector, I want to put diacritics on emoji...🤔̘͕̑ pfft, that looks silly) May 6, 2017 at 19:25
• You should add some test cases with non-ASCII output.
– xnor
May 6, 2017 at 22:02

Retina, 35 bytes

T̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯


Try it online!

Simply removes all characters in the ranges given in the challenge from the input. The code is super unreadable of course, but the code is conceptually no different from something like T0-9A-Za-z which would delete all alphanumeric characters.

• Seems unbeatable enough to me. May 6, 2017 at 20:12
• @EriktheOutgolfer I don't know, I think Jelly might be able to generate the code point ranges more efficiently than just listing the characters. May 6, 2017 at 20:13
• Actually I don't think it's able to. May 6, 2017 at 20:27
• I'm surprised there is no Jelly solution yet. May 7, 2017 at 23:00
• @icrieverytim here, and rip it's longer. I haven't figured out how to generate codepoints more effectively than this :P Sep 14, 2017 at 12:20

Python 3, 73 69 bytes

-4 bytes thanks to L3viathan.

Not sure if participating in your own challenge is ok or not but... Stole the regex and essentially the idea as well >< straight from the JS and Retina answers.

lambda s:re.sub('[̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯]','',s)
import re


Try it online!

• Save 4 bytes by making that a normal import statement. May 6, 2017 at 21:54
• You forgot to update the byte count.
– xnor
May 6, 2017 at 22:15
• @xnor Huh? Seems right to me. May 7, 2017 at 0:26
• @totallyhuman My mistake, missed that those char are multibyte.
– xnor
May 7, 2017 at 0:43
• Well, it's fair to say that I stole the character range from the Retina answer. (With care though, since my editor wanted to remove the zalgo along with the .)
– Neil
May 7, 2017 at 9:40

JavaScript (ES6), 55 bytes

f=
s=>s.replace(/[̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯]/g,'')
<textarea oninput=o.textContent=f(this.value)></textarea><pre id=o>

Japt, 37 bytes

r"[̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯]


Try it online!

PHP, 67 Bytes

shorter as the write out

<?=preg_replace("#[̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯]#u","",$argn);  Try it online! PHP, 115 Bytes <?=preg_replace("#[\u{300}-\u{36f}\u{1ab0}-\u{1aff}\u{1dc0}-\u{1dff}\u{20d0}-\u{20ff}\u{fe20}-\u{fe2f}]#u","",$argn);


Try it online!

PHP, 35 Bytes

Valid for the given Testcases it removes all Marks

<?=preg_replace("#\pM#u","",\$argn);


Try it online!

• @FelixDombek No it replaces only all Marks in the given ranges with nothing May 7, 2017 at 12:31

Python 3, 127 118 bytes

Just a straightforward answer for now, let's see how golfable it is.

lambda y:"".join(chr(x)for x in map(ord,y)if not(767<x<880or 6831<x<6912or 7615<x<7680or 8399<x<8448or 65055<x<65072))


Changelog:

• When will I ever learn that comprehensions are shorter than functional stuff (-9 bytes).
• 0or is not a thing, so you have to fix it or it will raise SyntaxError. May 6, 2017 at 20:01
• @EriktheOutgolfer Did you actually test it? Doesn't throw an error for me on neither Python 3 nor 2. May 6, 2017 at 20:09
• Oh right. I was confused for a bit. May 6, 2017 at 20:11

Bash + coreutils, 41

tr -d '̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯'


Simply strips out characters in the given ranges.

APL (Dyalog Unicode), 43 bytes

'[̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯]'⎕R''


Try it online!

PCRE Replace all those with nothing

44 byte version not using RegEx or strange character literals (and thus single byte per character):

⍞~⎕UCS∊65055 8399 7615 6831 767+⍳¨16×2 6~⍨⍳7


Try it online! ⍳7 1…7 (1 2 3 4 5 6 7)

2 6~⍨ except 2 and 6 (1 3 4 5 7)

16× multiply by 16 (16 48 64 80 112)

⍳¨ 1… each (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16, 1 2 3…, …110 111 112)

+ add offset to each list (65056 65057 65058…, …877 878 879)

∊ enlist (flatten)

⎕UCS convert to corresponding Unicode character

⍞~ get text input and remove all such characters

Jelly, 32 bytes

“Żȷ'⁺¦60ƭṖ_WTɦ7Ụ|ṫYɠF’bȷ5r2/FỌḟ@


Try it online!

Explanation

“Żȷ'⁺¦60ƭṖ_WTɦ7Ụ|ṫYɠF’bȷ5r2/FỌḟ@  Main link
“Żȷ'⁺¦60ƭṖ_WTɦ7Ụ|ṫYɠF’            Base 250 compressed integer; 768008790683206911076160767908400084476505665071
bȷ5         Convert into base 100000; [768, 879, 6832, 6911, 7616, 7679, 8400, 8447, 65056, 65071]
r2/      Inclusive range on non-overlapping slices of length 2
F     Flatten
Ọ    chr; cast to character from codepoints
ḟ@  Filter; remove all characters from input that are in the characters generated before

• o0 Didn't realize I bumped this question up lol. Is that b65072 what I think it is? :o Sep 14, 2017 at 12:21
• @icrieverytim yes numerical list compression :D Sep 14, 2017 at 12:23
• jelly is definitely the most zalgo language. i wonder what would happen if you ran the program on its own code? edit: unfortunately nothing Sep 14, 2017 at 13:15

Java 8, 57 bytes

s->s.replaceAll("[̀-ͯ᪰-᫿᷀-᷿⃐-⃿︠-︯]","")


Try it here.

05AB1E, 32 bytes

•3xIαEλ¤’ä₆Ćkмм0Â9"´•žHв2ôvyŸçK


Try it online!