|
 |
sscanf (PHP 4 >= 4.0.1, PHP 5) sscanf --
Разбирает строку в соответствии с заданным форматом
Описаниеmixed sscanf ( string str, string format [, mixed & ...] )
Функция sscanf() похожа на функцию
printf(), но используется не для вывода, а для
ввода данных. sscanf() интерпретирует строку
str в соответствии с форматом
format. Если переданы только эти два
аргумента, будет возвращен массив. В противном случае, считанные из
строки значения будкт присвоены переменным, переданным через
дополнительные аргументы, и будет возвращено количество присвоенных
значений. Дополнительные аргументы должны передаваться по ссылке.
Любые пробельные символы в строке формата соответствуют любым
пробельным символам во входной строке. Это значит, что например
символ табуляци \t в строке формата соответствует символу пробела во
входной строке.
Пример 1. sscanf() Example
<?php
list($serial) = sscanf("SN/2350001", "SN/%d");
$mandate = "Январь 01 2000";
list($month, $day, $year) = sscanf($mandate, "%s %d %d");
echo "Узел $serial был изготовлен: $year-" . substr($month, 0, 3) . "-$day\n";
?>
|
|
Если переданы необязательные аргументы, значения будут присвоены им,
а возвращено будет количество присвоенных значений.
Пример 2.
sscanf() - использование необязательных
аргументов
<?php
$auth = "24\tLewis Carroll";
$n = sscanf($auth, "%d\t%s %s", $id, $first, $last);
echo "<author id='$id'>
<firstname>$first</firstname>
<surname>$last</surname>
</author>\n";
?>
|
|
См. также описание функций fscanf(),
printf() и sprintf().
sscanf
skeltoac
22-Mar-2006 08:28
To parse a line from an Apache access log in common format:
<?php
$log = array();
$n = sscanf(trim($line), '%s %s %s [%[^]]] "%s %s %[^"]" %d %s "%[^"]" "%[^"]"',
$log['ip'],
$log['client'],
$log['user'],
$log['time'],
$log['method'],
$log['uri'],
$log['prot'],
$log['code'],
$log['bytes'],
$log['ref'],
$log['agent']
);
?>
Fuzzmaster
23-Sep-2005 07:14
Building a better Phone Format. This function, a variation of prev. posts (in theory):
Should stip all non-numeric characters.
Treat partial numbers as extensions.
Treat 8 - 9 digit numbers as phone+ext.
Be kind I'm a newbie.
<?php
Function formatPH($ph)
{
$ph = ereg_replace ('[^0-9]+', '', $ph); $phlen = strlen($ph);
switch (TRUE)
{
case ($phlen < 7):
$ext = $ph;
break;
case ($phlen == 7):
sscanf($ph, "%3s%4s", $pfx, $exc);
break;
case ($phlen > 7 AND $phlen < 10):
sscanf($ph, "%3s%4s%s", $pfx, $exc, $ext);
break;
case ($phlen == 10):
sscanf($ph, "%3s%3s%4s", $area, $pfx, $exc);
break;
case ($phlen == 11):
sscanf($ph, "%1s%3s%3s%4s", $cty, $area, $pfx, $exc);
break;
case ($phlen > 11):
sscanf($ph, "%1s%3s%3s%4s%s", $cty, $area, $pfx, $exc, $ext);
break;
}
$out = '';
$out .= isset($cty) ? $cty.' ' : '';
$out .= isset($area) ? '('.$area.') ' : '';
$out .= isset($pfx) ? $pfx.' - ' : '';
$out .= isset($exc) ? $exc.' ' : '';
$out .= isset($ext) ? 'x'.$ext : '';
return $out;
}
?>
Brainiac361
22-Aug-2005 01:49
The %[^[]]-trick may seem to work, but it doesn't!
What happens is that sscanf will simply match any characters but an opening square bracket (which is rather rare and that's why it might just seem to work).
But even worse it will expect a ]-character next and continue to match anything.
Now what you can do is make sscanf look for any character but a character that is really never used... a good choice is the linebreak "%[^\\n]", especially in combination with fscanf.
What you can also do is copy and paste any unused ascii character like #001 or something.
joshmckenneyATgmailDOT(0{
14-Jul-2005 03:21
added country code (1) to phone number function:
function formatPhone($phone) {
if (empty($phone)) return "";
if (strlen($phone) == 7)
sscanf($phone, "%3s%4s", $prefix, $exchange);
else if (strlen($phone) == 10)
sscanf($phone, "%3s%3s%4s", $area, $prefix, $exchange);
else if (strlen($phone) > 10)
if(substr($phone,0,1)=='1') {
sscanf($phone, "%1s%3s%3s%4s", $country, $area, $prefix, $exchange);
}
else{
sscanf($phone, "%3s%3s%4s%s", $area, $prefix, $exchange, $extension);
}
else
return "unknown phone format: $phone";
$out = "";
$out .= isset($country) ? $country.' ' : '';
$out .= isset($area) ? '(' . $area . ') ' : '';
$out .= $prefix . '-' . $exchange;
$out .= isset($extension) ? ' x' . $extension : '';
return $out;
}
Vincent Jansen
16-Jun-2005 01:04
If you just wants filter out information between two parts of a string, i used the following, it works better for me then the sscanf function.
<?php
function scanstr($zoekstr,$part1,$part2) {
$firstpos=strpos ($zoekstr, $part1)+strlen($part1);
$lastpos=strpos ($zoekstr, $part2);
$scanresult=substr ($zoekstr, $firstpos, $lastpos-$firstpos);
return($scanresult);
}
echo scanstr ("var1=hello&var2=test&var3=more","var2=","&var3");
?>
codeslinger at compsalot dot com
06-Feb-2005 06:03
Security Note:
Although it is a very powerful technique, keep in mind that it is easily deceived.
Many successful exploits have been based on scanf attacks. It should not be used on untrusted input without a lot of additional validation.
steve (atsign) rapaport *fullstop* com
18-Sep-2004 04:27
The classic example
<?php
list($month, $day, $year) = sscanf($mandate, "%s %d %d");
?>
works fine if you already know the variable names you want to fill, and the format string you want to fill them with. If you want both of those to be dynamically configurable (as in reading a file with a flexible format), you may have a use for this code:
Assumes your variables are listed in the variable
$varstr = "var1, var2, var3"
(you don't know what the variable names will be,
perhaps they're a subset of a long list of valid ones)
Assumes your input line is in $line, and your sscanf spec is in $spec. Both of these may also be in your input.
Integrity checks omitted for clarity.
<?php
$vars = explode(',', $varstr);
$values = @sscanf($line, $spec);
foreach ($vars as $var) {
$var = trim($var);
$next = each($values);
$$var = $next['value'];
if ($$var) $result_array[$var] = $$var;
}
?>
This took me some time to write successfully, so I'm including it for posterity. Non-obvious is the use of
$next.
Cheers,
Steve
marcus at synchromedia dot co dot uk
24-Mar-2003 09:38
In PHP >= 4.3.0, if you use additional reference parameters, you will get this warning:
PHP Warning: Call-time pass-by-reference has been deprecated - argument passed by value
This clearly has the potential to cause unexpected consequences (vars left empty), and will break existing code. So don't do it! These docs need updating to say this too.
The syntax:
list($a, $b) = sscanf("hello world", "%s %s");
will work as expected, and doesn't seem to cause any problems with Apache that I've noticed.
sbarnum.pointsystems@com
19-Feb-2003 01:29
This is a better phone format function than the one above, handles leading zeroes correctly, by using the "%s" instead of "%d" argument to sscanf(). Again, this function assumes that the input has been stripped of all non-integer values.
function formatPhone($phone) {
if (empty($phone)) return "";
if (strlen($phone) == 7)
sscanf($phone, "%3s%4s", $prefix, $exchange);
else if (strlen($phone) == 10)
sscanf($phone, "%3s%3s%4s", $area, $prefix, $exchange);
else if (strlen($phone) > 10)
sscanf($phone, "%3s%3s%4s%s", $area, $prefix, $exchange, $extension);
else
return "unknown phone format: $phone";
$out = "";
$out .= isset($area) ? '(' . $area . ') ' : "";
$out .= $prefix . '-' . $exchange;
$out .= isset($extension) ? ' x' . $extension : "";
return $out;
}
sbarnum.pointsystems@com
19-Nov-2002 07:21
More fun with phones! This assumes that the phone number is 10 digits, with only numeric data, but it would be easy to check the length of the string first.
function formatPhone($phone) {
if (empty($phone)) return "";
sscanf($phone, "%3d%3d%4d", $area, $prefix, $exchange);
$out = @$area ? "($area) " : "";
$out .= $prefix . '-' . $exchange;
return $out;
}
jon at fuck dot org
13-Sep-2002 11:27
this function is a great way to get integer rgb values from the html equivalent hex.
list($r, $g, $b) = sscanf('00ccff', '%2x%2x%2x');
jamesDOTwatsonATrealismstudiosDOTcom
10-Jul-2002 12:31
You're making a common mistake in believing that sscanf (and the whole scanf family) are more intelligent than they really are, sscanf always starts checking from the first character of the string, the first character that doesn't match the format string causes it to bail out early, if you want to match later in the string you'll have to do something like this:
sscanf(strstr($lit[$x],"Vol."),"Vol. %d",&$vol[$x]);
(check the docs on strstr if you're unsure of how it works)
or if you want you can add some simple error correction
$temp=strstr($lit[$x],"Vol.");
if ($temp)
sscanf($temp,"Vol. %d",&$vol[$x]);
else
$vol[$x]=$default_vol;
ryany at pantek dot com
03-Apr-2002 08:27
not only does that match anything, but so does .*
elgabos at umail dot ucsb dot edu
27-Feb-2002 03:38
After playing around with this for a while, I found that if you use %[^[]] instead of %s (since php has problems with spaces when using %s) it works nicely.
For those that aren't familiar with regular expressions, %[^[]] basically matches anything that isn't nothing.
Hope this helps. - Gabe
narainsbrain at yahoo dot com
14-Oct-2001 03:25
apparently, sscanf always splits at spaces, even if spaces are not specified in the format. consider this script:
<?php
$str = "This is a\tsentence with\ttabs";
$scanned = sscanf($str, "%s\t%s\t%s");
echo join(" : ", $scanned);
?>
this echoes "This : is : a", not the expected "This is a : sentence with : tabs."
this behaviour is fine if your strings don't contain spaces, but if they do you'd be better off using explode().
owenh at halo5 dot com
28-Nov-2000 04:21
list($phone11, $phone12, $phone13) = sscanf($arow[9],"(%d) %d-%d");
If thoes variables dont have data in them it seems to cause segfaults on apache. ( just to save you some trouble shooting time here is my fix:
sscanf($arow[9],"(%d) %d-%d", &$phone11,&$phone12, &$phone13);
clcollie at mindspring dot com
12-Sep-2000 04:59
Actually sscanf()_always_ returns an array if you specify less return variables than format specifiers. i may change this to return a scalar if only a single format specifier exists.
Note that sscanf() is (almost) the complete functional equivalent of its "C" counterpart, so you can do the following to get the expected effect :
sscanf("SN/2350001","SN/%d",&$serial)
The array return was a nicety for PHP.
| |