tags:

views:

186

answers:

7

I am trying to write a small php application and i am facing a problem. This is suppose to get text like :

this is *noun but it is *name.

And should take the words that start with a star and add them to the string tokens. However this is not working.

// get list of fields (each should have words delimited by underscores
$storyArray = split(' ', $story);
$tokens = ""; // space-delimited list of fields
for ($i = 0; $i < count($storyArray); $i++) {
    if ($storyArray[$i][0] == '*')
     $tokens .= $storyArray[$i] + " ";
}
$tokensArray = split(' ', $tokens);
A: 

On your if statement, change:

if ($storyArray[$i][0] == '*')

To:

if ($storyArray[$i]{0} == '*')
Matt
that didn't change anything :(
c2009l123
-1: `{}` for strings is deprecated in PHP5. `[]` is correct. A string is an array of characters.
Andrew Moore
@Matt: nothing to do with that IMHO
RageZ
From the manual: **Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. However, this syntax is deprecated as of PHP 5.3.0. Use square brackets instead, such as $str[42].**
deceze
but how to access the first char in an array because it seems that $storyArray[$i][0] is the syntax for a multidimensional array and not the first letter of the string $storyArray
c2009l123
+4  A: 

This worked for me:

$story = "this is *noun but it is *name";

$storyArray = split(' ', $story);
$tokens = array();
for ($i = 0; $i < count($storyArray); $i++) {
  if ($storyArray[$i][0] == '*') {
    array_push($tokens, substr($storyArray[$i], 1));
  }
}
var_dump($tokens);
$tokenString = implode(" ", $tokens);

Note that I'm pushing the tokens directly into an array, then imploding it.

jheddings
+1 Put them in an array directly if what you need is an array anyway. I'd suggest `$tokens[] = $story...`, but that's just me.
deceze
can i make it instead of an array just a string that is separated by spaces and without the star, so it would like : "noun_1 noun_1 adjective" etc ?
c2009l123
You could implode the array like $string_of_tokens = implode(" ", $tokens)
Jeff
You bet... Just use the `substr` and `implode` functions. I updated my answer with an example.
jheddings
so what i have now is this :$storyArray = split(' ', $story);$newTokens = array();for ($i = 0; $i < count($storyArray); $i++) { if ($storyArray[$i][0] == '*') { array_push($newTokens, $storyArray[$i]); }}$tokens = implode(" ", $newTokens);but it is not working :)
c2009l123
+9  A: 

Wow, I can't believe I've been debugging this and missing the obvious fault!

This line here:

$tokens .= $storyArray[$i] + " ";

You must concatenate with a period (.), not a plus sign! What you have right now is basically the same as $tokens .= 0;

Matt
Just had the same *D'uh!* experience. :o)
deceze
+1 I missed that too.
Asaph
+3  A: 

"+" is for addition, not string concatenation. It casts its arguments as numbers, which will always be 0 in your source.

On another note, splitting $tokens is unnecessary. Instead, append tokens to $tokensArray:

$story = "this is *noun but it is *name";
// get list of fields (each should have words delimited by underscores
$storyArray = split(' ', $story);
$tokens = ""; // space-delimited list of fields
$tokensArray=array();
for ($i = 0; $i < count($storyArray); $i++) {
    if ($storyArray[$i][0] == '*') {  
        $tokens .= $storyArray[$i] . " ";
        $tokensArray[] = $storyArray[$i];
    }
}

If you only needed $tokens for generating $tokensArray, you can get rid of it. Also, depending on whether you need $storyArray, preg_match_all(...) might be able to replace your code:

preg_match_all('/\*\w+/', $story, $tokensArray);
$tokensArray = $tokensArray[0];
outis
i am trying to print a table on the screen with text boxes for people to fill in the info from that (NOT WORKING:():echo "<form action=\"story.php\" method=\"post\"> <input name=\"fields\" type=\"hidden\" value=\"$tokens\" /> <input name=\"story\" type=\"hidden\" value=\"$story\" /> <table>";for ($i = 0; $i < count($tokenArray); $i++) { $fieldWords = split('_',$tokensArray[$i]); echo "<tr><td>"; echo $fieldWords[0]; for ($j = 1; $j < count($fieldWords); $j++) { echo " ".$fieldWords[$j]; } echo ":"; echo "</td><td><input name=\"$tokensArray[$i]\" type=\"text\" /></td></tr>";}
c2009l123
i will post it in a different questiton :)
c2009l123
+1  A: 

Replace

$tokens .= $storyArray[$i] + " ";

with

$tokens .= $storyArray[$i]." ";

And

$tokensArray = split(' ', $tokens);

with

$tokensArray = split(' ', rtrim($tokens));
jitter
+3  A: 

You can also use a regular expression to achieve the same effect, without all the string manipulation you are doing right now. This would be the most elegant solution:

$string = "this is *noun but it is *name";

// Lets set up an empty array
$tokens = array();

preg_match_all('/\*\w+/m', $string, $tokens);
$tokens = $tokens[0]; // Only one sub-pattern, dropping unnecessary dimension.

var_dump($tokens);

Regular expressions exists to do mainly exactly the kind of task you are trying to achieve now. They are usually faster than doing string manipulations manually (Regular Expression engine in PHP is compiled code).

To explain my regex:

  • /: start boundary
  • \*: an asterisk (*)
  • \w: any alpha-numeric character or underscore
  • +: previous marker, 1 or more times. (match \w one or more times)
  • /: end boundary
  • m: multiline modifier
Andrew Moore
Also you can use the regexpr pattern `\b` for *word boundary* instead of spaces.
Bill Karwin
Yes, but unfortunately, `*` is considered to be a *word boundary*, so it will not work in this case.
Andrew Moore
+1  A: 
$tokens .= $storyArray[$i] + " ";

in this line, you should be using the . operator to concatenate strings.

vsr