# Extract substring by repeated StringPattern

This code failed, but may exemplify my intention.

StringCases["aA1bbbbbbbbbbaA2baA3b...aA4b",Repeated[Shortest["a"~~xx__~~"b"],{2,100}]]


I want to get the substring "aA2baA3b". They (a~~__~~b is one string pattern) are in succession.

single "aA3b" is not expected to get and should be omitted.

StringCases["aA1bbbbbbbbbbaA2baA3b...aA4b",Repeated[Shortest["a"~~__~~"b"],{2,100}]]


gives

"aA1bbbbbbbbbbaA2baA3b"

-
In my opinion, it is bad behavior to ask one question, get an answer, and then edit the question, obliterating the original, into something quite different. You should preserve the original question in your edits, and add the new one as a clearly marked edit – m_goldberg Jul 13 '13 at 8:01
I think You should tell us what do You want to do. Not what result You want to get, because it can be obtained in many ways. Those solutions will fail in general because they were created to work with special case. – Kuba Jul 13 '13 at 8:13
@m_goldberg Ok, I'll take care of that in the future. – HyperGroups Jul 13 '13 at 8:34

## 2 Answers

As I said already in chat, what's breaking your neck here is the naming of the pattern xx_. So if you leave that out, everything should work

StringCases["aA1baA2baA3b...aA4b",
Repeated[Shortest["a" ~~ __ ~~ "b"], {2, 100}]]

(* {"aA1baA2baA3b"} *)


Let me elaborate in more detail, why this happens. If you name the pattern, it can no longer stand for everything in each single repetition. It needs to be the same then. For the purpose of demonstration let me simplify your example to

StringCases["aA1baA2baA3b...aA4b",
Shortest["a" ~~ xx__ ~~ "b"] :> xx]

(* {"A1", "A2", "A3", "A4"} *)


As you see, we get a list of results from StringCases and in each result the xx_ stands for something else. Now lets assume we want 2 repetitions of your pattern, but we just write them down, without using Repeated

StringCases["aA1baA2baA3b...aA4b",
PatternSequence[Shortest["a" ~~ xx__ ~~ "b"], Shortest["a" ~~ xx__ ~~ "b"]]]

(* {} *)


this brings no result, because you force with the naming of the pattern, that it is the same in both appearances. But for such a thing nothing matches. When you now change "aA2b" to "aA1b"1, you get a match, because then you have two equal things which can fill xx__.

## Update

Regarding your comment

Hi, I add one case, StringCases["aA1bbbbbbbbbbaA2baA3b...aA4b",Repeated[Shortest["a"~~__~~"b"],‌​{2,100}]], how can I only get "aA2baA3b" – HyperGroups 7 hours ago

Mr.Wizards answer is completely sound, but let me give another solution different to him. The question here is, what you are trying to achieve, because if feels like you are throwing example after example only to see how it is done.

Let me first explain what happens in your comments example. The first repetition of Shortest["a"~~__~~"b"] is matched as follows

"a" ~~ "A1bbbbbbbbb" ~~ "b"


which is perfectly fine. What you can do at this point is say I only want one "b" matched. Then you could say that the __ is allowed to match everything Except a "b":

StringCases["aA1bbbbbbbbbbaA2baA3b...aA4b",
Repeated[Shortest["a" ~~ Except["b"] .. ~~ "b"], {2, 100}]]

-
Hi, I add one case,StringCases["aA1bbbbbbbbbbaA2baA3b...aA4b",Repeated[Shortest["a"~~__~~"b"],‌​{2,100}]], how can I only get aA2baA3b – HyperGroups Jul 13 '13 at 3:36
@HyperGroups See my update. – halirutan Jul 13 '13 at 11:29

Regarding your revised question you may be seeking something like this:

StringCases[
"aA1bbbbbbbbbbaA2baA3b...aA4b",
Repeated[Shortest["a" ~~ __ ~~ "b"], {2, 100}],
Overlaps -> True
]

{"aA1bbbbbbbbbbaA2baA3b", "aA2baA3b"}


You can use SortBy[%, StringLength] // First to get the shortest of these results.

-
Yes, something like this, If we are doing StringReplace, I wonder whether there could be one direct string pattern to search and replace. – HyperGroups Jul 13 '13 at 10:59