Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks! I can't figure out how to match a series of characters and spaces within two '()'.

The problem is $3. I'm trying to match the following expression.

$_ =~ /^ALTER\s+TABLE\s+(\w+)\s+ADD\s+CONSTRAINT\s+(\w+)\s+PRIMARY\s+K +EY\s+\(\s*(.)\s*)/; $table=$1; $name=$2; $col=$3; ---DATA--- ALTER TABLE ORDERS ADD CONSTRAINT PK_ORDER_ORDER_NUM PRIMARY KEY ( ORD +ER_NUM) ; ALTER TABLE ORDER_ITEMS ADD CONSTRAINT PK_ORDER_NUM_ITEMS PRIMARY KEY +( ORDER_NUM, ITEM_NUM, SUB_TYPE ) ;
What am I doing wrong?

Replies are listed 'Best First'.
Re: Need a regex for matching multiple words within parentheses
by hanenkamp (Pilgrim) on Dec 12, 2003 at 18:42 UTC

    There are a couple obvious problems.

    First, (.). in the third match should contain a quantifier and you should be careful of "." as a greedy match will swallow the end parenthesis and cause the match to fail. I'd use (\S+) or (.+?).

    Second, you should have another backslash before the very last closing parenthesis.

    Note: I didn't take the time to test these recommendations.

    Update: Er...duh, don't do that...

    Update: That is, don't do the striked one, it will get the first word (or more if there is no whitespace between), but the other works fine. Sorry, I was unclear.

      Er...duh, don't do that...

      Why not? Your suggestion - with (.+?) - works fine for me:

      while ( <DATA> ) { if ( /^ALTER\s+TABLE\s+ (\w+) # $1 \s+ADD\s+CONSTRAINT\s+ (\w+) # $2 \s+PRIMARY\s+KEY\s+\(\s* (.+?) # $3 \s*\)/x ) { print "\$1: <$1> \$2: <$2> \$3: <$3>\n"; } } __DATA__ ALTER TABLE ORDERS ADD CONSTRAINT PK_ORDER_ORDER_NUM PRIMARY KEY ( ORD +ER_NUM) ALTER TABLE ORDER_ITEMS ADD CONSTRAINT PK_ORDER_NUM_ITEMS PRIMARY KEY +( ORDER_NUM, ITEM_NUM, SUB_TYPE )

      ++hanenkamp (or have I missed something?)

      dave

Re: Need a regex for matching multiple words within parentheses
by ysth (Canon) on Dec 12, 2003 at 18:39 UTC
    () are special regex grouping characters. To match literal () characters, put a \ before them.

    Update: apparently I can't read a simple question. Your parens are doing just fine, but you need a +? after the . in (.)