$不匹配作为最后一个字符的换行符之前的位置。
理想情况下,/ 1... $ /应匹配,但匹配的情况与/1 / $ /似乎是错误的。
可能是什么原因?
PHP doc还说一个美元字符($)是一个断言,只有当前匹配点位于主题字符串的末尾时,或者紧接在作为最后一个字符的换行符之前,该断言才为TRUE。 string(默认情况下)。
$subject = 'abc#
123#
';
$pattern = '/1...$/';
preg_match_all($pattern,$subject,$matches); // no match
更新 由于换行符的\ r \ n格式,我怀疑有额外的点。 我做了以下实验并看到了一些提示。
$pattern = '/1...(.)$/';
echo bin2hex($matches[1]); // 28
28似乎等于\ r \ n(CR)所以基本上$在\ n之前匹配\ n而不是\ r \ n之前,这可能是我问题的原因。
打开不可打印字符后的图像
答案 0 :(得分:3)
问题是由于窗口文件和linux文件的不同换行符表示
为什么会出现这个问题:
以下实验证实了同样的情况:
$subject = 'abc#
123#
';
$pattern = '/1...(.)$/';
preg_match_all($pattern,$subject,$matches);
echo bin2hex($matches[1]); // 28
// 28 is equivalent of \r or CR(carriage return)
在linux系统中创建新文件,/ 1... $ /捕获匹配:)
我希望如果遇到同样的问题,这会节省一些人的时间。
答案 1 :(得分:2)
你的字符串是多行的。默认情况下,正则表达式不会做多行。您必须添加m
修饰符才能实现此目的。
例如:
/1...$/m
答案 2 :(得分:0)
我已经被困在这个问题上两天了。我做了很多测试,找到了这背后的任何逻辑,因为这完全取决于数据的来源(内部和受控对外部和不受控制)。在我的例子中,它是我的网站上的输入字段(<textarea>
),可从各种浏览器(和各种操作系统)获得,并且在JavaScript中没有模式测试/匹配/检查的问题。以下是那些试图在多行模式(/ m)的任何行的末尾($)正确匹配模式的问题(或至少解决)的人的提示。
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
// C 3 p 0 _
$pat1='/\w$/mi'; // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi'; // Slightly better
$pat3='/\w\R?$/mi'; // Somehow disappointing according to php.net and pcre.org when used improperly
$pat4='/\w(?=\R)/i'; // Much better with allowed lookahead assertion (just to detect without capture) without multiline (/m) mode; note that with alternative for end of string ((?=\R|$)) it would grab all 7 elements as expected
$pat5='/\w\v?$/mi';
$pat6='/(*ANYCRLF)\w$/mi'; // Excellent but undocumented on php.net at the moment (described on pcre.org and en.wikipedia.org)
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
$t=preg_match_all($pat6, $str, $m6);
echo $str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
."\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
."\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
."\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
."\n5 !!! $pat5 ($s): ".print_r($m5[0], true)
."\n6 !!! $pat6 ($t): ".print_r($m6[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 and $pat4 (\R), $pat5 (\v) and altered newline option in $pat6 ((*ANYCRLF)) - for some applications at least.
/* The code above results in the following output:
ABC ABC
123 123
def def
nop nop
890 890
QRS QRS
~-_ ~-_
1 !!! /\w$/mi (3): Array
(
[0] => C
[1] => 0
[2] => _
)
2 !!! /\w\r?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
3 !!! /\w\R?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
4 !!! /\w(?=\R)/i (6): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
)
5 !!! /\w\v?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
6 !!! /(*ANYCRLF)\w$/mi (7): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
[6] => _
)
*/
?>
不幸的是,我无法访问使用最新PHP版本的服务器 - 我的本地PHP为5.3.8,而我的公共主机PHP版本为5.2.17。