perl - force matching

for below perl code, if without ?, will print test, otherwise will print null.
i know it is due to greedy perl regexp matching that eat out test by previous .*, i also know there should be a way to force perl to match if can match, can anyone help me to figure it out or lead me to the right direction?

my $str="This is a testing string";
print $1 if $str=~/This.*(test)?.*$/;

Probably misunderstanding you here, but what's wrong with:

print $1 if $str=~/This.*(test).*$/;

That matches a "This", followed by zero-or-more of anything, followed by "test", followed by zero-or-more of anything, up to the end of the line.

On my machine it just prints "test". Could you post desired output, pls.?

Problem:-
You have a pattern with a greedy quantifier like *, +, ?, or {}, and you want to stop it from being greedy.
A classic case of this is the na�ve substitution to remove tags from HTML. Although it looks appealing,
s#<TT>.*</TT>##gsi, actually deletes everything from the first open TT tag through the last closing one
This would turn "Even <TT>vi</TT> can edit <TT>troff</TT> effectively." into "Even
effectively", completely changing the meaning of the sentence!

Solution
Replace the offending greedy quantifier with the corresponding non-greedy version. That is, change *, +, ?,
and {} into *?, +?, ??, and {}?, respectively.
perl -wle '
$str="This is a testing string";
print $1 if $str=~/This.*?(test).*$/;
' infile.txt

Hope I answer you question.
;);):wink:

I hope Tom and Nat answered your question.

--Tom Christiansen, Nathan Torkington, "The Perl Cookbook, 2nd Edition" O'Reilly & Associates, May 1999, Chapter 6, Section 15 ;);):wink:

it doesn't matter if you know this info or not but it is great if you know where to look for your question in books

By Tom Christiansen & Nathan Torkington; ISBN 1-56592-243-3, 794 pages.
First Edition, August 1998.

;);):wink:
:cool::cool::cool:

Right my mistake, I had incorrectly cited the source material you did not cite as the source of your post, as being the 2nd Edition of the Perl Cookbook. It is indeed the First Edition where you got that from. Thank you for the correction.

hi all,

thanks very much for your reply.

probably i did not express myself clearly.

please refer to below code and expected output.

actually what i need is:
1> if no match, just let greedy * eat out the following
2> if match, should not eat out

code:

my @arr=("This is a testing string","This is a tesing string");
map {print $1,"\n" if /This.*?(test)?.*$/} @arr;
print "--\n";

expect output:

test (here there do have test, so have to force math)
(here no match, so just nothing)
--