正则表达式 - \\ n和\ n的区别

时间:2015-06-13 21:39:24

标签: php regex datetime syntax scanf

很抱歉在互联网上添加另一个“正则表达式解释”问题,但我必须知道原因。我已经通过RegexBuddy和Regex101.com运行了这个正则表达式,没有任何帮助。

我在调试时间解析函数时遇到了以下正则表达式("%4d%[^\\n]")。我不时会收到“无效日期”错误,但仅限于1月和6月。我嘲笑了一些代码来重新创建正在发生的事情,但我无法弄清楚为什么删除一个斜杠会修复它。

<?php
$format = '%Y/%b/%d';
$random_date_strings = array(
    '2015/Jan/03',
    '1985/Feb/13',
    '2001/Mar/25',
    '1948/Apr/02',
    '1948/May/19',
    '2020/Jun/22',
    '1867/Jul/09',
    '1901/Aug/11',
    '1945/Sep/21',
    '2000/Oct/31',
    '2009/Nov/24',
    '2015/Dec/02'
    );

$year = null;
$rest_of_string = null;

echo 'Bad Regex:';
echo '<br/><br/>';
foreach ($random_date_strings as $date_string) {
    sscanf($date_string, "%4d%[^\\n]", $year, $rest_of_string);
    print_data($date_string, $year, $rest_of_string);
}

echo 'Good Regex:';
echo '<br/><br/>';
foreach ($random_date_strings as $date_string) {
    sscanf($date_string, "%4d%[^\n]", $year, $rest_of_string);
    print_data($date_string, $year, $rest_of_string);
}

function print_data($d, $y, $r) {

    echo 'Date string: ' . $d;
    echo '<br/>';
    echo 'Year: ' . $y;
    echo '<br/>';
    echo 'Rest of string: ' . $r;
    echo '<br/>';
}
?>

随意在本地运行,但我关注的唯一两个输出是六月和一月的月份。 "%4d%[^\\n]"会将$rest_of_string截断为/Ju/Ja,而"%4d%[^\n]"会按预期显示字符串的其余部分(/Jan/03&amp; {{1} })。

这是我对错误的正则表达式的解释:

  • /Jun/22 - 获取四位数。
  • %4d% - 查找字符串开头和新行之间的数字。

任何人都可以请更正我的解释和/或告诉我为什么删除斜线会给我我期望的结果?

我不关心如何...我需要为什么。

1 个答案:

答案 0 :(得分:1)

就像@LucasTrzesniewski指出的那样,这是sscanf()语法,它与Regex无关。格式在sprintf()页面中进行了解释。

在您的模式"%4d%[^\\n]"中,两个\\会转换为单个反斜杠字符。所以对“错误”模式的正确解释是:

  • %4d - 获取四位数。
  • %[^\\n] - 查找不是反斜杠或字母“n”的所有字符

这就是为什么它匹配“Jan”和“Jun”中的“n”之前的所有内容。

正确的模式是"%4d%[^\n]",其中\ n转换为新的行字符,它的解释是:

  • %4d - 获取四位数。
  • %[^\n] - 查找非新行的所有字符