Skip to main content
brought With[] outside a bit for clarity
Source Link
Philip Maymin
  • 1.2k
  • 8
  • 12

Okay, I think here's a way you can do virtually everything you want.

First, my original answer, which I then had then moved to a comment to Mr.Wizard's answer.

You can substitute in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}

(* {True, True} *)

This gives you what you want for your specific case.

But, you may want to have an arbitrarily long repeated sequence. Meaning, you don't know if it will repeat exactly 2 times or 3 times. The above doesn't do that.

Well, now, I don't know how to do it completely arbitrarily, but if you're willing to choose some maximum, then the following seems to work (but please correct me if I'm wrong):

StringMatchQ[#, Table[StringExpression @@ With[With[{each = p__ /; endsWithSpaceQ[p]}, Table[eachStringMatchQ[#, Table[StringExpression @@ Table[each /. p -> Unique[], {i}]]], {i, 10 10}] ~~ "17"] "17"] & /@ {str1, str2}]

(replace the "10" in the last iterator with whatever your maximum is)

The way it works is to first create the sequence of patterns programmatically, as Mr.Wizard suggested. For that, it replicates the "p" pattern a certain i number of times and replaces it with a unique symbol each time it appears. Then, the outer table iterates i up through the maximum. A list of StringExpression's evaluates as an alternative, so as long as one of those patterns matches, it goes on.

Here's a way to see that it is really working. Let's change your function a little bit:

endsWithSpaceQn[str_, lenprespace_: 3] := StringEndsQ[str, " "] && StringLength@str == lenprespace + 1

now we are looking for strings that end with a space and are of length 3 (not counting the space)

Running the abovethis:

With[{each = p__ /; endsWithSpaceQn[p, 3]}, StringMatchQ[#, Table[StringExpression @@ Table[each /. p -> Unique[], {i}], {i, 10}] ~~ "17"] & /@ {str1, str2}]

with any maximum greater than 1 in the final iterator (where the 10 is), results in the correct answer:

(* {True, True} *)

But if you replace the 10 with a 1 then you'll see it comes back as:

(* {False, False} *)

(if you had used the original endsWithSpaceQ function here, it would still come back true, because it would match eg "abc abc ")

Okay, I think here's a way you can do virtually everything you want.

First, my original answer, which I then had moved to a comment to Mr.Wizard's answer.

You can substitute in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}

(* {True, True} *)

This gives you what you want for your specific case.

But, you may want to have an arbitrarily long repeated sequence. Meaning, you don't know if it will repeat exactly 2 times or 3 times.

Well, I don't know how to do it completely arbitrarily, but if you're willing to choose some maximum, then the following seems to work (but please correct me if I'm wrong):

StringMatchQ[#, Table[StringExpression @@ With[{each = p__ /; endsWithSpaceQ[p]}, Table[each /. p -> Unique[], {i}]], {i, 10}] ~~ "17"] & /@ {str1, str2}

(replace the "10" in the last iterator with whatever your maximum is)

The way it works is to first create the sequence of patterns programmatically, as Mr.Wizard suggested. For that, it replicates the "p" pattern a certain i number of times and replaces it with a unique symbol each time it appears. Then, the outer table iterates i up through the maximum. A list of StringExpression's evaluates as an alternative, so as long as one of those patterns matches, it goes on.

Here's a way to see that it is really working. Let's change your function a little bit:

endsWithSpaceQn[str_, lenprespace_: 3] := StringEndsQ[str, " "] && StringLength@str == lenprespace + 1

now we are looking for strings that end with a space and are of length 3 (not counting the space)

Running the above with any maximum greater than 1 in the final iterator (where the 10 is), results in the correct answer:

(* {True, True} *)

But if you replace the 10 with a 1 then you'll see it comes back as:

(* {False, False} *)

(if you had used the original endsWithSpaceQ function here, it would still come back true, because it would match eg "abc abc ")

Okay, I think here's a way you can do virtually everything you want.

First, my original answer, which I had then moved to a comment to Mr.Wizard's answer.

You can substitute in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}

(* {True, True} *)

This gives you what you want for your specific case.

But, you may want to have an arbitrarily long repeated sequence. Meaning, you don't know if it will repeat exactly 2 times or 3 times. The above doesn't do that.

Well, now, I don't know how to do it completely arbitrarily, but if you're willing to choose some maximum, then the following seems to work:

With[{each = p__ /; endsWithSpaceQ[p]}, StringMatchQ[#, Table[StringExpression @@ Table[each /. p -> Unique[], {i}], {i, 10}] ~~ "17"] & /@ {str1, str2}]

(replace the "10" in the last iterator with whatever your maximum is)

The way it works is to first create the sequence of patterns programmatically, as Mr.Wizard suggested. For that, it replicates the "p" pattern a certain i number of times and replaces it with a unique symbol each time it appears. Then, the outer table iterates i up through the maximum. A list of StringExpression's evaluates as an alternative, so as long as one of those patterns matches, it goes on.

Here's a way to see that it is really working. Let's change your function a little bit:

endsWithSpaceQn[str_, lenprespace_: 3] := StringEndsQ[str, " "] && StringLength@str == lenprespace + 1

now we are looking for strings that end with a space and are of length 3 (not counting the space)

Running this:

With[{each = p__ /; endsWithSpaceQn[p, 3]}, StringMatchQ[#, Table[StringExpression @@ Table[each /. p -> Unique[], {i}], {i, 10}] ~~ "17"] & /@ {str1, str2}]

with any maximum greater than 1 in the final iterator (where the 10 is), results in the correct answer:

(* {True, True} *)

But if you replace the 10 with a 1 then you'll see it comes back as:

(* {False, False} *)

(if you had used the original endsWithSpaceQ function here, it would still come back true, because it would match eg "abc abc ")

generalized to almost arbitrary repetitions so undeleted
Source Link
Philip Maymin
  • 1.2k
  • 8
  • 12

(moving Okay, I think here's a way you can do virtually everything you want.

First, my original answer, which I then had moved to a comment to Mr.Wizard's answer.

You can substitute in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}

(* {True, True} *)

This gives you what you want for your specific case.

But, you may want to have an arbitrarily long repeated sequence. Meaning, you don't know if it will repeat exactly 2 times or 3 times.

Well, I don't know how to do it completely arbitrarily, but if you're willing to choose some maximum, then the following seems to work (but please correct me if I'm wrong):

StringMatchQ[#, Table[StringExpression @@ With[{each = p__ /; endsWithSpaceQ[p]}, Table[each /. p -> Unique[], {i}]], {i, 10}] ~~ "17"] & /@ {str1, str2}

(replace the "10" in the last iterator with whatever your maximum is)

The way it works is to first create the sequence of patterns programmatically, as Mr.Wizard suggested. For that, it doesn't allow arbitrary repetitionreplicates the "p" pattern a certain i number of times and replaces it with a unique symbol each time it appears. Then, the outer table iterates i up through the maximum. A list of StringExpression's evaluates as an alternative, so as long as one of those patterns matches, it goes on.

Here's a way to see that it is really working. Let's change your function a little bit:

endsWithSpaceQn[str_, lenprespace_: 3] := StringEndsQ[str, " "] && StringLength@str == lenprespace + 1

now we are looking for strings that end with a space and are of length 3 (not counting the space)

Running the above with any maximum greater than 1 in the final iterator (where the 10 is), results in the correct answer:

(* {True, True} *)

But if you replace the 10 with a 1 then you'll see it comes back as:

(* {False, False} *)

(if you had used the original endsWithSpaceQ function here, it would still come back true, because it would match eg "abc abc ")

(moving to a comment to Mr.Wizard's answer, as it doesn't allow arbitrary repetition)

Okay, I think here's a way you can do virtually everything you want.

First, my original answer, which I then had moved to a comment to Mr.Wizard's answer.

You can substitute in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}

(* {True, True} *)

This gives you what you want for your specific case.

But, you may want to have an arbitrarily long repeated sequence. Meaning, you don't know if it will repeat exactly 2 times or 3 times.

Well, I don't know how to do it completely arbitrarily, but if you're willing to choose some maximum, then the following seems to work (but please correct me if I'm wrong):

StringMatchQ[#, Table[StringExpression @@ With[{each = p__ /; endsWithSpaceQ[p]}, Table[each /. p -> Unique[], {i}]], {i, 10}] ~~ "17"] & /@ {str1, str2}

(replace the "10" in the last iterator with whatever your maximum is)

The way it works is to first create the sequence of patterns programmatically, as Mr.Wizard suggested. For that, it replicates the "p" pattern a certain i number of times and replaces it with a unique symbol each time it appears. Then, the outer table iterates i up through the maximum. A list of StringExpression's evaluates as an alternative, so as long as one of those patterns matches, it goes on.

Here's a way to see that it is really working. Let's change your function a little bit:

endsWithSpaceQn[str_, lenprespace_: 3] := StringEndsQ[str, " "] && StringLength@str == lenprespace + 1

now we are looking for strings that end with a space and are of length 3 (not counting the space)

Running the above with any maximum greater than 1 in the final iterator (where the 10 is), results in the correct answer:

(* {True, True} *)

But if you replace the 10 with a 1 then you'll see it comes back as:

(* {False, False} *)

(if you had used the original endsWithSpaceQ function here, it would still come back true, because it would match eg "abc abc ")

Post Undeleted by Philip Maymin
Post Deleted by Philip Maymin
moving to comment instead
Source Link
Philip Maymin
  • 1.2k
  • 8
  • 12

How about substituting in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}(moving to a comment to Mr.Wizard's answer, as it doesn't allow arbitrary repetition)

How about substituting in Unique:

StringMatchQ[#, StringExpression @@ With[{each = p__ /; endsWithSpaceQ@p}, Table[each /. p -> Unique[], {2}]] ~~ "17"] & /@ {str1, str2}

(moving to a comment to Mr.Wizard's answer, as it doesn't allow arbitrary repetition)

Source Link
Philip Maymin
  • 1.2k
  • 8
  • 12
Loading