Regex (ECMAScript or better), 20 bytes
s/(.)(?!.*␀.*\1)//sg
Try it online! - ECMAScript 2018
Try it online! - Perl
Try it online! - PCRE2
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
This is a single regex substitution, to be applied once. Input is taken in the form of the two strings delimited by NUL (ASCII 0).
Above and below, ␀
represents what is actually a raw NUL character in the regex.
s/ # Begin substitution - match the following:
(.) # \1 = one character
(?! # Negative lookahead - match if the following can't match:
.* # Skip over as many characters as possible, minimum zero, to make
# the following match:
␀ # Skip over the NUL delimiter
.* # Skip over as many characters as possible, minimum zero, to make
# the following match:
\1 # Match the character we captured in \1
)
/ # Substitution - replace with the following:
# Empty string
/ # Flags:
s # single line - "." will match anything, including newline
g # global - find and replace all matches, going from left to right
This automatically erases the NUL and everything following it, because NUL and all characters following it are themselves not followed by NUL, so the negative lookahead matches for each of them.
(More test harnesses to come.)
As far as ECMAScript goes, this requires ECMAScript 2018 (aka ES9) due to the use of the s
flag.
In Ruby, the m
flag is used, which is the Ruby equivalent of what is s
in most other regex engines.
\$\large\textit{Anonymous functions}\$
Perl, 42 bytes
sub{$_=join'␀',@_;s/(.)(?!.*␀.*\1)//sg;$_}
Try it online!
Takes the two strings as arguments.
Beaten by a 35 byte solution based on an unposted solution by Sisyphus: Try it online!
Ruby, 42 41 bytes
-1 byte thanks to Steffan
->s,a{(s+?␀+a).gsub /(.)(?!.*␀.*\1)/m,''}
Try it online!
$args-join'␀'-creplace'(?s)(.)(?!.*␀.*\1)'
Try it online!
Takes the two strings as arguments.
JavaScript (ES9), 43 bytes
a=>a.join`␀`.replace(/(.)(?!.*␀.*\1)/sg,'')
Try it online!
Takes a list containing the two strings.
Java, 52 bytes
s->a->(s+"␀"+a).replaceAll("(?s)(.)(?!.*␀.*\\1)","")
Attempt This Online!
\$\large\textit{Full programs}\$
Perl, 37 bytes
$_=join'',<>;s/(.)(?!.*␀.*\1)//sg;say
Try it online!
Takes multiline input (terminated by EOF) using NUL as a delimiter between the two strings.
Beaten by a 19 byte solution based on an unposted solution by Sisyphus: Try it online! (they should really post it), or 25 bytes to insert chomp;
at the beginning if being picky about the output being followed by a NUL.
intersection/3
\$\endgroup\$