How to implement this by RegularExpression
my $s1 = 'a1a2a3a4a5';
my $pat = '(ad(?=ad)ad)';
while($s1 =~ m/$pat/g)
{
print "$1n"
}
I want to get output:
a1a2a3
a2a3a4
a3a4a5
But output is:
a1a2
a3a4
By my knowledge, next match in loop is started from ?=, but by my practice, it is not work in this way. Who can point out the problem.
Thanks
perl
add a comment |
my $s1 = 'a1a2a3a4a5';
my $pat = '(ad(?=ad)ad)';
while($s1 =~ m/$pat/g)
{
print "$1n"
}
I want to get output:
a1a2a3
a2a3a4
a3a4a5
But output is:
a1a2
a3a4
By my knowledge, next match in loop is started from ?=, but by my practice, it is not work in this way. Who can point out the problem.
Thanks
perl
add a comment |
my $s1 = 'a1a2a3a4a5';
my $pat = '(ad(?=ad)ad)';
while($s1 =~ m/$pat/g)
{
print "$1n"
}
I want to get output:
a1a2a3
a2a3a4
a3a4a5
But output is:
a1a2
a3a4
By my knowledge, next match in loop is started from ?=, but by my practice, it is not work in this way. Who can point out the problem.
Thanks
perl
my $s1 = 'a1a2a3a4a5';
my $pat = '(ad(?=ad)ad)';
while($s1 =~ m/$pat/g)
{
print "$1n"
}
I want to get output:
a1a2a3
a2a3a4
a3a4a5
But output is:
a1a2
a3a4
By my knowledge, next match in loop is started from ?=, but by my practice, it is not work in this way. Who can point out the problem.
Thanks
perl
perl
asked Jan 2 at 3:42
user2799433user2799433
234
234
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
.... next match in loop is started from ?=
The next match within //g
is started where the last match left off. A (?=...)
does not magically set the position where the next match will start; it simply checks if the part inside (?=...)
would match at the current position without advancing the position.
If your regex would be /(ad(?=ad))/
then the match would be done after the first ad
although it makes sure that there is a second ad
behind it. But your regex is /(ad(?=ad)ad)/
which means simplified regarding the match /adad/
, i.e. it is done after the second ad
.
What you could do to achieve what you want is for example the following:
my $s1 = 'a1a2a3a4a5';
while($s1 =~ m/(ad(?=(adad)))/g)
{
print "$1$2n"
}
This will put the first ad
into $1
, capture the second adad
into $2
but still finish the match after the first ad
. Only you need to print "$1$2"
then instead of only "$1"
.
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
@user2799433: right: the(?=pat1)
only looks if the pattern exists but does not move the end of the match. But thepat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern forpat1
andpat2
(i.e.(?=pat)pat
) the positive lookahead(?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.
– Steffen Ullrich
Jan 3 at 8:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000971%2fhow-to-implement-this-by-regularexpression%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
.... next match in loop is started from ?=
The next match within //g
is started where the last match left off. A (?=...)
does not magically set the position where the next match will start; it simply checks if the part inside (?=...)
would match at the current position without advancing the position.
If your regex would be /(ad(?=ad))/
then the match would be done after the first ad
although it makes sure that there is a second ad
behind it. But your regex is /(ad(?=ad)ad)/
which means simplified regarding the match /adad/
, i.e. it is done after the second ad
.
What you could do to achieve what you want is for example the following:
my $s1 = 'a1a2a3a4a5';
while($s1 =~ m/(ad(?=(adad)))/g)
{
print "$1$2n"
}
This will put the first ad
into $1
, capture the second adad
into $2
but still finish the match after the first ad
. Only you need to print "$1$2"
then instead of only "$1"
.
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
@user2799433: right: the(?=pat1)
only looks if the pattern exists but does not move the end of the match. But thepat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern forpat1
andpat2
(i.e.(?=pat)pat
) the positive lookahead(?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.
– Steffen Ullrich
Jan 3 at 8:19
add a comment |
.... next match in loop is started from ?=
The next match within //g
is started where the last match left off. A (?=...)
does not magically set the position where the next match will start; it simply checks if the part inside (?=...)
would match at the current position without advancing the position.
If your regex would be /(ad(?=ad))/
then the match would be done after the first ad
although it makes sure that there is a second ad
behind it. But your regex is /(ad(?=ad)ad)/
which means simplified regarding the match /adad/
, i.e. it is done after the second ad
.
What you could do to achieve what you want is for example the following:
my $s1 = 'a1a2a3a4a5';
while($s1 =~ m/(ad(?=(adad)))/g)
{
print "$1$2n"
}
This will put the first ad
into $1
, capture the second adad
into $2
but still finish the match after the first ad
. Only you need to print "$1$2"
then instead of only "$1"
.
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
@user2799433: right: the(?=pat1)
only looks if the pattern exists but does not move the end of the match. But thepat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern forpat1
andpat2
(i.e.(?=pat)pat
) the positive lookahead(?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.
– Steffen Ullrich
Jan 3 at 8:19
add a comment |
.... next match in loop is started from ?=
The next match within //g
is started where the last match left off. A (?=...)
does not magically set the position where the next match will start; it simply checks if the part inside (?=...)
would match at the current position without advancing the position.
If your regex would be /(ad(?=ad))/
then the match would be done after the first ad
although it makes sure that there is a second ad
behind it. But your regex is /(ad(?=ad)ad)/
which means simplified regarding the match /adad/
, i.e. it is done after the second ad
.
What you could do to achieve what you want is for example the following:
my $s1 = 'a1a2a3a4a5';
while($s1 =~ m/(ad(?=(adad)))/g)
{
print "$1$2n"
}
This will put the first ad
into $1
, capture the second adad
into $2
but still finish the match after the first ad
. Only you need to print "$1$2"
then instead of only "$1"
.
.... next match in loop is started from ?=
The next match within //g
is started where the last match left off. A (?=...)
does not magically set the position where the next match will start; it simply checks if the part inside (?=...)
would match at the current position without advancing the position.
If your regex would be /(ad(?=ad))/
then the match would be done after the first ad
although it makes sure that there is a second ad
behind it. But your regex is /(ad(?=ad)ad)/
which means simplified regarding the match /adad/
, i.e. it is done after the second ad
.
What you could do to achieve what you want is for example the following:
my $s1 = 'a1a2a3a4a5';
while($s1 =~ m/(ad(?=(adad)))/g)
{
print "$1$2n"
}
This will put the first ad
into $1
, capture the second adad
into $2
but still finish the match after the first ad
. Only you need to print "$1$2"
then instead of only "$1"
.
edited Jan 2 at 17:51
ikegami
265k11178401
265k11178401
answered Jan 2 at 4:14
Steffen UllrichSteffen Ullrich
61.6k358100
61.6k358100
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
@user2799433: right: the(?=pat1)
only looks if the pattern exists but does not move the end of the match. But thepat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern forpat1
andpat2
(i.e.(?=pat)pat
) the positive lookahead(?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.
– Steffen Ullrich
Jan 3 at 8:19
add a comment |
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
@user2799433: right: the(?=pat1)
only looks if the pattern exists but does not move the end of the match. But thepat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern forpat1
andpat2
(i.e.(?=pat)pat
) the positive lookahead(?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.
– Steffen Ullrich
Jan 3 at 8:19
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
By my understand, (?=pat1)pat2 only take a look whether there is a pat1 at current matching position but do not match it to move current matching position. Then continue to match pat2 at current match position and then advance the position. Right?
– user2799433
Jan 3 at 7:45
@user2799433: right: the
(?=pat1)
only looks if the pattern exists but does not move the end of the match. But the pat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern for pat1
and pat2
(i.e. (?=pat)pat
) the positive lookahead (?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.– Steffen Ullrich
Jan 3 at 8:19
@user2799433: right: the
(?=pat1)
only looks if the pattern exists but does not move the end of the match. But the pat2
then actually matches and also moves the end of the match. Since you essentially used the same pattern for pat1
and pat2
(i.e. (?=pat)pat
) the positive lookahead (?=pat)
was essentially irrelevant since it was followed by exactly the same pattern with a "real" match, i.e. the lookahead and the real match started and ended at the same position.– Steffen Ullrich
Jan 3 at 8:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000971%2fhow-to-implement-this-by-regularexpression%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown