# The SBEVE Challenge

She said s(he) be(lie)ve(d), he said sbeve.

Input

• A non-empty string, s. It's guaranteed that s will have only printable ASCII characters and at least one word (defined as [A-Za-z0-9]+) in parentheses, and all parentheses will be closed respectively.

Output

• A string containing all non-whitespace characters (whitespaces are defined as spaces, tabs, carriage returns, new lines, vertical tabs and form feeds characters) that are not in parentheses.

Test cases

Input -> Output
s(he) be(lie)ve(d) -> sbeve
s(h3) (1s) br(0k)3n -> sbr3n
(I) (K)now (Ill) Be
(My) Best (Self) -> nowBeBest
sho(u)lder (should)er
s(ho)u(ld)er s(h)ould(er) -> sholderersuersould
p(er)f(ection) -> pf
(hello) (world) ->


The last output is an empty string.

This is so shortest code in bytes wins.

• Are all whitespace characters guaranteed to be spaces? – Jonathan Allan Mar 8 at 16:58
• I think all answers so far assumed whitespaces were limited to spaces due to the examples :( – Jonathan Allan Mar 8 at 17:10
• @Jonathan Allan I'm sorry, I tried to demonstrate a new line in examples 3 and 4, but I think it was mistaken for text wrap. I'll make it more explicit, thanks! – Enzo Mar 8 at 17:18
• All parentheses will be closed, But will all of them be opened? (: – Ad Hoc Garf Hunter Mar 8 at 17:25
• It's guaranteed that s will have only printable ASCII characters. "Printable ASCII" means code points from 32 to 126 (both included), and therefore the only whitespace allowed in the input is the normal space character (so no tabs, newlines etc). Can you confirm, and perhaps edit the challenge text accordingly? – Luis Mendo Mar 8 at 23:30

# Jelly, 11 bytes

>Ƈ⁶Ø(yṣ”)m2


A full program printing the result.

Try it online!

### How?

Whitespace printable ASCII characters are "\t\r\n\f\v " and non-whitespace printable ASCII are all greater than ' ', so:

>Ƈ⁶Ø(yṣ”)m2 - Link: list of printable ASCII characters, s
Ƈ          - filter keep those (characters) for which:
> ⁶         -   greater than literal space character
Ø(       - literal list of characters ['(', ')']
y      - translate (replace all '(' with ')')
”)   - literal ')' character
ṣ     - split at
m2 - modulo-two-slice (every other entry)
- implicit, smashing print


# 05AB1E, 16 bytes

ηʒ„()S¢Æ_}€θJžKÃ


### Explanation

η                         - Prefixes of the string
ʒ       }                - filter these when...
„()S¢                   - the counts of ( and ) characters
Æ_                 - are the same
€θ              - get the last character from each of these prefixes
J             - Join all these last characters
žKÃ          - and remove any that aren't in [a-zA-Z0-9]


# Retina, 11 bytes

$$.*?$$|\s



(Note the trailing newline in the code).

Try it online!

### How it works

                 Replace either
.*             a sequence of characters
          in parentheses,
?            matched non-greedily,
|         or
\s       any whitespace character
by nothing


# Bash + GNU utilities, 3632 28 bytes

xargs|sed 's/([^)]*)\|\s//g'


Try it online!

Thanks to @user41805 for 4 bytes!

• I believe xargs can take the place of tr – user41805 Mar 10 at 17:46
• @user41805 Thank you -- great trick1 – Mitchell Spector Mar 11 at 0:55

# SNOBOL4 (CSNOBOL4), 119 bytes

 I =INPUT
S I ARB . L '(' ARB ')' REM . I :F(W)
O =O L :(S)
W O NOTANY(&UCASE &LCASE 84 ** 9) ='' :S(W)
OUTPUT =O
END


Try it online!

# Jelly, 12 bytes

e€Ø(œpm2FfØB


Try it online!

A monadic link taking and returning a Jelly string. Now handles other whitespace characters.

## Alternative 12 bytes

Ø(yṣ”)m2FfØB


Try it online!

• Fails the test cases containing newline characters. – Jonathan Allan Mar 8 at 17:27
• @JonathanAllan to be fair they weren’t there until 9 minutes ago! – Nick Kennedy Mar 8 at 17:34
• They were there from revision 1, just not that obvious. – Jonathan Allan Mar 8 at 17:36
• @JonathanAllan ok, thanks. Fixed. – Nick Kennedy Mar 8 at 17:37

# APL+WIN, 25 bytes or 30 bytes

Prompts for string.

((~x∨≠\x←s∊'()')/s←⎕)~' '


Try it online! Courtesy of Dyalog Classic

If I now have to handle none alphanumeric characters this works for 5 extra bytes in APL+WIN but will not work in Dyalog Classic so no TIO

((~x∨≠\x←s∊'()')/s←⎕)~⎕av[⍳33]

• Fails the test cases containing newline characters. – Jonathan Allan Mar 8 at 17:27
• @JonathanAllan I have modified my code to handle the newline character but the spec seems to be continually evolving. I think I will bow out rather than trying to keep up! – Graham Mar 8 at 17:59
• You can always delete and come back later, but I think most issues have been ironed out. Printable ASCII in s, balanced parentheses, whitespace are ordinals 9, 10, 11, 12, 13, and 32. – Jonathan Allan Mar 8 at 18:04

# 05AB1E, 12 bytes

ŒʒÁ„)(å}KžKÃ


Try it online!

Œ               # substrings
ʒ     }        # filter, keep each substring if:
Á             #  after being rotated right
„)(å         #  it contains ")("
K       # remove those substrings from the input
žKÃ    # keep only characters in [a-zA-Z0-9]

• Nice didn't realise that K would work like that, I didn't try it because I thought it would remove the text in between brackets too.. but I guess it applies each consecutively? – Expired Data Mar 9 at 12:12
• Yup, K (and similar operators like :, .: and .;) applies substitutions one by one. – Grimmy Mar 9 at 12:13
• Since my 10-byter using the split and uninterleave builtins was quite different from both of your answers, I decided to post it as a separated answer. – Kevin Cruijssen Mar 10 at 7:18

# 05AB1E, 10 bytes

žuS¡ιнJžKÃ


Explanation:

žu          # Push builtin "()<>[]{}"
S         # Split it to a list of characters: ["(",")","<",">","[","]","{","}"]
¡        # Split the (implicit) input-string by that
ι       # Uninterleave this list
н      # Only keep the first inner list
J     # Join it together to a single string
žKÃ  # And only keep the characters [a-zA-Z0-9]
# (after which the result is output implicitly)


# Python 3, 47 45 bytes

Saved 2 bytes thanks to FryAmTheEggman!!!

lambda s:re.sub(r"$$\w+$$|\s","",s)
import re


Try it online!

# Stax, 11 bytes

û┼╢╕jN&╪º╛╘


Run and debug it

Unpacked:

"$$.*?$$| "zR


this is just a simple regex replace. It replaces all strings that match /$$.*?$$| / with z (an empty string)

# Japt, 12 bytes

r"%s|%(.*?%)


Try it

# Charcoal, 18 bytes

Φθ∧›ι ⁼№…θ⊕κ(№…θκ)


Try it online! Link is to verbose version of code. Explanation:

 θ                  Input string
Φ                   Filtered where
ι               Current character
›                Is not whitespace
∧                 Logical And
№            Count of
(       Open parentheses
…θ⊕κ        In input string so far (inclusive)
⁼             Equals
№      Count of
)  Close parentheses
…θκ   In input string so far (exclusive)


# Perl 5-p0, 15 bytes

s/\s|$$.*?$$//g


Try it online!

# sed, 32 31 bytes

:l;s/([^)]*)\|\s//g;N;s/\n//;tl


Try it online!

Shaved off one byte by removing the -E option and just using basic regular expressions, surprisingly :-) .

sed is almost perfect for this challenge. The only issue is that sed is a stream editor, processing one line at a time: the trailing newline on each line is not processed, which doesn't make it straightforward to delete any newline characters.

So here's how this script does it:

:l

s/([^)]*)\|\s//g
Delete all parenthetical expressions and whitespace before the first newline.

N
If we're not at the last line, append the next line to the pattern space.  (The next line is appended immediately _after_ the \n at the end of the previous line.  That \n is still there, now in the middle of the pattern space, where it's available for processing by sed.)

s/\n//
Delete a \n in the middle of the pattern space, if any.  (There will be one if we weren't at the last line in the previous step already.)

tl
If the last command found a \n to delete, jump back to label l, and do it again!

• Hint: there's a flag in GNU sed (since 4.2.2 or something) that slurps all those newline-delimited lines – user41805 Mar 10 at 17:44
• @user41805 Thanks, I'll check it out. I thought I reviewed all the sed flags, but maybe I was looking at old documentation, or maybe I missed it. – Mitchell Spector Mar 11 at 4:27

# C (gcc), 70 bytes

f(char*s){for(;*s;)s=*s-40?isalnum(*s)&&putchar(*s),s+1:strchr(s,41);}


Try it online!

• Suggest index() instead of strchr() – ceilingcat Mar 9 at 20:45

# Erlang (escript), 128 bytes

e(X)->[lists:nth(I*2-1,X)||I<-lists:seq(1,length(X)div 2)].
s(B)->e(string:split([if N==40->41;1<2->N end||N<-B,N>32],")",all)).


Try it online!

# Wj, 14 13 bytes

Not very satisfied with this.

♥ú≈Γ♣◄├╙▄û▲▌∩


## Uncompressed

cV<:'),kS'(,=W^
W   % Keep all satisfying the condition
c                % All items in the non-mapped string
V<              % That are less than the current iteration index
:             % Make 2 copies
'),k         % Copy #1: Split on )
S'(,     % Copy #2: Split on (
=    % Are their lengths equal?
% If an array is compared to a number,
% The array length is returned first
^  % Keep only characters satisfying [a-zA-z0-9]

Flag:j           % Implicit join the output array
$$$$


# Red, 52 bytes

func[s][parse trim/all s[any[to"("remove thru")"]]s]


Try it online!

# JavaScript (Node.js), 30 bytes

s=>s.replace(/$$.*?$$|\s/g,"")


Try it online!

# APL (Dyalog Extended), 21 19 bytes

∊⊢⊆⍨<>(≠\∨⊢)⍤∊∘'()'


Try it online!

### How it works

∊⊢⊆⍨<>(≠\∨⊢)⍤∊∘'()'  ⍝ Input: string s
∊∘'()'  ⍝ Boolean vector (1 if a member of '()')
(≠\  )⍤        ⍝ Scan by boolean XOR
⍝ (gives 1 between '()'s, including '(' but not ')')
∨⊢          ⍝ Include back ')'
>               ⍝ Bitmask indicating negation of the above,
<                ⍝ plus each char not being whitespace
∊⊢⊆⍨                 ⍝ Filter s by the bitmask above


Boolean filtering uses this APL golfing tip.

# Gema, 7 characters

(*)=
=


Sample run:

bash-5.0\$ gema '(*)=; =' <<< 's(he) be(lie)ve(d)'
sbeve


# Kotlin, 75 bytes

{fold(""){a,v->when(v){')'->a.takeWhile{it!='('}
in " \r\n"->a
else->a+v}}}
`

Try it online!