4
$\begingroup$

If I compute this:

 StringCases["abczabvncz", "a" ~~ __ ~~ "z"]

It yields:

{"abczabvncz"}

But I wanted it to take string from "a" to the nearest "z" like:

{"abcz","abvncz"}

I tried to use Repeated[p,n] but the trouble for me is that in the text I'm applying this, there is no guarantee of minimum of maximum between "a" and "z". I would have to use some notion of "nearest z".

$\endgroup$
1
  • 5
    $\begingroup$ StringCases["abczabvncz", Shortest["a" ~~ __ ~~ "z"]] gives the expected result {"abcz", "abvncz"} $\endgroup$
    – vindobona
    Commented May 19 at 0:00

3 Answers 3

7
$\begingroup$
str = "abczabvncz";

Borrowing the Shortest-pattern from vindobona (but with a triple underscore)

p = StringPosition[str, Shortest["a" ~~ ___ ~~ "z"]]

{{1, 4}, {5, 10}}

StringTake[str, p]

{"abcz", "abvncz"}

Another example:

str = "azabczabvncz";

p = StringPosition[str, Shortest["a" ~~ ___ ~~ "z"]]

{{1, 2}, {3, 6}, {7, 12}}

StringTake[str, p]

{"az", "abcz", "abvncz"}

$\endgroup$
4
$\begingroup$
StringCases["abczabvncz", "a" ~~ Except["z"] ... ~~ "z"]

StringCases["abczabvncz", RegularExpression["a.*?z"]]

StringCases["abczabvncz", RegularExpression["a[^z]*z"]]

(* and with credit going to vindobona... *)
StringCases["abczabvncz", Shortest["a" ~~ ___ ~~ "z"]]
(* Although, note the ___ rather than __, which would allow you to match when a and z were adjacent. *)

You might also be interested in the Overlaps option for StringCases. For example,

StringCases["abczabvncz", "a" ~~ __ ~~ "z", Overlaps -> All]
(* {"abczabvncz", "abcz", "abvncz"} *)
$\endgroup$
2
$\begingroup$

Using sequence-functions (they get slow with long lists)

c = Characters["azabczabvncz"]

{"a", "z", "a", "b", "c", "z", "a", "b", "v", "n", "c", "z"}

Pre-define pattern for better readability

p = {"a", Except["a"] ..., "z"};

Using SequenceCases

SequenceCases[c, w : p :> StringJoin[w]]

{"az", "abcz", "abvncz"}

Using SequenceSplit (new in 11.3)

SequenceSplit[c, w : p :> StringJoin[w]]

{"az", "abcz", "abvncz"}

Using SequencePosition

q = SequencePosition[c, p]

{{1, 2}, {3, 6}, {7, 12}}

StringJoin @ Take[c, #] & /@ q

{"az", "abcz", "abvncz"}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.