3

I need to pick up all texts between the first and last parentheses but am having a hard time with regex.

What I have is this so far and I'm stuck and don't know hot to proceed further.

/(\w+)\((.*?)\)\s/g)

But it stops at the first ")" that it sees.

Sample:

(me)

(mine)

((me) and (you))

Desired output is

me

mine

(me) and (you)
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Vic Mac
  • 33
  • 1
  • 4

4 Answers4

2

Your code is almost correct, it would worked only if you would not add the ? in the regex, for example: (I have also removed a couple of things)

/\w+\((.*)\)/
sergiotarxz
  • 520
  • 2
  • 14
1

Since you want to capture all text inside parenthesis, you shouldn't use non-greedy quantifier. You can use this regex which uses lookarounds and greedy version .* which captures all text in between ( and ).

(?<=\().*(?=\))

Demo

EDIT: Another alternative solution

Another way to extract same data can be done using following regex which doesn't have any look ahead/behind which is not supported by some regex flavors and might be useful in those situations.

^\((.*)\)$

Here ^\( matches the starting bracket and then (.*) consumes any text in a exhaustive manner and places in first grouping pattern and only stops at last occurrence of ) before end of line.

Demo without lookaround

Pushpesh Kumar Rajwanshi
  • 18,127
  • 2
  • 19
  • 36
  • 1
    Thanks! I looked at the demo and it is what I wanted. I still need to familiarise myself with LookBehind and LookAhead. – Vic Mac Feb 14 '19 at 16:30
  • @VicMac: You can read about look arounds [here](https://www.regular-expressions.info/lookaround.html) This is a good site for learning basic to advanced regex. If my answer helped you, consider accepting it. – Pushpesh Kumar Rajwanshi Feb 14 '19 at 16:32
  • @VicMac this is the most easiest answer to understand lookahead & lookbehind. See https://stackoverflow.com/a/2973495/1138192 – A l w a y s S u n n y Feb 14 '19 at 16:36
  • 1
    Using a lookahead is more complicated than necessary for this task. Use them when you need to match against text without actually consuming it (so that a later part of the regular expression will still see them). – chepner Feb 14 '19 at 17:55
  • @chepner: You are right and of course there are multiple ways of extracting data and the lookaround regex can easily be written as `\((.*)\)` which is a simple regex not having lookaround where data can be extracted from first grouping pattern like this in [demo](https://regex101.com/r/kHKiy6/2) – Pushpesh Kumar Rajwanshi Feb 14 '19 at 18:28
1

Here's a non-regex solution. Since you want the absolute first and last instances of fixed substrings, index and rindex find the right positions that you can feed to substr:

#!/usr/bin/perl
use v5.10;

while( <DATA> ) {
    chomp;

    my $start = 1 +  index $_, '(';
    my $end   =     rindex $_, ')';
    my $s = substr $_, $start, ($end - $start);

    say "Read: $_";
    say "Extracted: $s";
    }


__END__
(me)
(mine)
((me) and (you))
brian d foy
  • 129,424
  • 31
  • 207
  • 592
0

A non-regex way with chop() and reverse()

$string='((me) and (you))';
chop($string);
$string = reverse($string);
chop($string); 
$string = reverse($string); 
print $string;

Output:

(me) and (you)

DEMO: http://tpcg.io/MhaLed

A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103
  • Reversing the string twice is overkill. If you just want to remove the first and last characters (which doesn't, by the way, actually solve the original problem of capturing text between parentheses), the just use `substr $string, 1, -1`. – chepner Feb 14 '19 at 17:52