When I try to figure out this problem,I write such code:
words = Catenate[
WordList[#, Language -> "English",
IncludeInflections -> True] & /@ {"KnownWords", "Stopwords"}];
string = StringReplace[
"What is the best approach to a problem like this in Mathematica?",
" " -> ""];
StringCases[string, __?(MemberQ[words, ToLowerCase[#]] &)]
{"WhatisthebestapproachtoaproblemlikethisinMathematica"}
But I am confused why I get whole string?What's mistake I have made?
Answer
You commented on July 6th:
but I don't understand still why the
?
cannot work totally and give wholestring
.
As MarcoB already quoted:
In a form such as __?test, every element in the sequence matched by __ must yield True when test is applied.
You can easily see for yourself that this is true.
words = {"is", "a", "problem"};
StringCases["What is the best approach to a problem?", __?(MemberQ[words, #] &)]
{"a", "a", "a", "a"}
More explicitly we can use Print
or Sow
as the test function(1) to see exactly which expressions are being tested:
Reap[ StringCases["Mathematica", __?Sow] ][[2, 1]]
{"M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "a", "a", "a", "a", "a",
"a", "a", "a", "a", "a", "t", "t", "t", "t", "t", "t", "t", "t", "t", "h", "h",
"h", "h", "h", "h", "h", "h", "e", "e", "e", "e", "e", "e", "e", "m", "m", "m",
"m", "m", "m", "a", "a", "a", "a", "a", "t", "t", "t", "t", "i", "i", "i", "c",
"c", "a"}
Observe that:
- Only single letter strings are ever tested
- 66 matches are attempted due to every test failing (11 + 10 + 9 + 8 ...)
The first point is actually very useful behavior and I direct you to my own answer Using a PatternTest versus a Condition for pattern matching for additional examples.
The second point is the deleterious consequence of extremely flexible pattern matching used in Mathematica which allows the test function itself to be stateful. I personally feel that there should be a more efficient matching scheme available as an alternative as many uses do not require this level of generality.
Contrast this with Condition
(short form /;
)
Reap[ StringCases["Mathematica", x__ /; Sow[x]] ][[2, 1]]
{"Mathematica", "Mathematic", "Mathemati", "Mathemat", "Mathema", "Mathem",
"Mathe", "Math", "Mat", "Ma", "M", "athematica", "athematic", "athemati",
"athemat", "athema", "athem", "athe", "ath", "at", "a", "thematica", "thematic",
"themati", "themat", "thema", "them", "the", "th", "t", "hematica", "hematic",
"hemati", "hemat", "hema", "hem", "he", "h", "ematica", "ematic", "emati", "emat",
"ema", "em", "e", "matica", "matic", "mati", "mat", "ma", "m", "atica", "atic",
"ati", "at", "a", "tica", "tic", "ti", "t", "ica", "ic", "i", "ca", "c", "a"}
Here we see that every possible alignment is tried, with the entire candidate sequence passed to the test function each time.
Comments
Post a Comment