首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用PHP检测EOL类型

使用PHP检测EOL类型
EN

Stack Overflow用户
提问于 2012-06-16 20:38:19
回答 5查看 15.4K关注 0票数 13

参考:,这是一个自我回答的问题.它的目的是分享知识,问答风格。

如何在PHP中检测线路末端字符的类型?

PS:我从头到尾写这段代码已经太久了,所以我决定分享它,另外,我肯定有人会找到改进的方法。

EN

回答 5

Stack Overflow用户

发布于 2014-07-24 07:12:32

这里已经给出的答案为用户提供了足够的信息。下面的代码(基于已经给出的anwers)可能会有更多帮助:

  • 它提供了对已发现的EOL的参考。
  • 检测还设置了一个密钥,可由应用程序用于此引用。
  • 它展示了如何在实用程序类中使用引用。
  • 演示如何使用它检测返回已找到的EOL的键名的文件。

我希望这对你们大家都有用。

代码语言:javascript
运行
复制
/**
Newline characters in different Operating Systems
The names given to the different sequences are:
============================================================================================
NewL  Chars       Name     Description
----- ----------- -------- ------------------------------------------------------------------
LF    0x0A        UNIX     Apple OSX, UNIX, Linux
CR    0x0D        TRS80    Commodore, Acorn BBC, ZX Spectrum, TRS-80, Apple II family, etc
LFCR  0x0A 0x0D   ACORN    Acorn BBC and RISC OS spooled text output.
CRLF  0x0D 0x0A   WINDOWS  Microsoft Windows, DEC TOPS-10, RT-11 and most other early non-Unix
                          and non-IBM OSes, CP/M, MP/M, DOS (MS-DOS, PC DOS, etc.), OS/2,
----- ----------- -------- ------------------------------------------------------------------
*/
const EOL_UNIX    = 'lf';        // Code: \n
const EOL_TRS80   = 'cr';        // Code: \r
const EOL_ACORN   = 'lfcr';      // Code: \n \r
const EOL_WINDOWS = 'crlf';      // Code: \r \n

然后在静态类实用程序中使用以下代码来检测

代码语言:javascript
运行
复制
/**
Detects the end-of-line character of a string.
@param string $str      The string to check.
@param string $key      [io] Name of the detected eol key.
@return string The detected EOL, or default one.
*/
public static function detectEOL($str, &$key) {
   static $eols = array(
     Util::EOL_ACORN   => "\n\r",  // 0x0A - 0x0D - acorn BBC
     Util::EOL_WINDOWS => "\r\n",  // 0x0D - 0x0A - Windows, DOS OS/2
     Util::EOL_UNIX    => "\n",    // 0x0A -      - Unix, OSX
     Util::EOL_TRS80   => "\r",    // 0x0D -      - Apple ][, TRS80
  );

  $key = "";
  $curCount = 0;
  $curEol = '';
  foreach($eols as $k => $eol) {
     if( ($count = substr_count($str, $eol)) > $curCount) {
        $curCount = $count;
        $curEol = $eol;
        $key = $k;
     }
  }
  return $curEol;
}  // detectEOL

然后对于一个文件:

代码语言:javascript
运行
复制
/**
Detects the EOL of an file by checking the first line.
@param string  $fileName    File to be tested (full pathname).
@return boolean false | Used key = enum('cr', 'lf', crlf').
@uses detectEOL
*/
public static function detectFileEOL($fileName) {
   if (!file_exists($fileName)) {
     return false;
   }

   // Gets the line length
   $handle = @fopen($fileName, "r");
   if ($handle === false) {
      return false;
   }
   $line = fgets($handle);
   $key = "";
   <Your-Class-Name>::detectEOL($line, $key);

   return $key;
}  // detectFileEOL

将您的类名称更改为实现类的名称(所有静态成员)。

票数 4
EN

Stack Overflow用户

发布于 2016-10-24 20:33:09

我的答案,因为我既不能使奥哈尔的一个,也不能转西维的一个工作,是:

代码语言:javascript
运行
复制
function detect_newline_type($content) {
    $arr = array_count_values(
               explode(
                   ' ',
                   preg_replace(
                       '/[^\r\n]*(\r\n|\n|\r)/',
                       '\1 ',
                       $content
                   )
               )
           );
    arsort($arr);
    return key($arr);
}

解释:

两种拟议解决方案的总体思路都很好,但实施细节妨碍了这些答案的有用性。

实际上,这个函数的目的是返回文件中使用的换行符类型,并且该换行符可以是一个或两个字符长的

仅这一点就会导致str_split()的使用不正确。正确剪切令牌的唯一方法是使用一个函数,该函数根据字符检测来裁剪长度可变的字符串。这就是explode()发挥作用的时候。

但是为了给有用的标记爆炸,有必要用正确的匹配替换正确的字符,在适当的数量。大部分魔法发生在正则表达式中。

必须考虑3点:

  1. 按照.*的建议使用奥哈尔是行不通的。虽然.确实不匹配换行符,但在系统中,\r不是换行符,或者是换行符的一部分,但.将不正确地匹配换行符(提醒:我们正在检测换行符,因为它们可能与系统上的换行符不同。否则就没有意义)。
  2. 用任何东西替换/[^\r\n]*/将“工作”以使文本消失,但是只要我们想要一个分隔符(因为我们删除了除换行符以外的所有字符,任何不是换行符的字符都将是有效的分隔符),这将是一个问题。因此,使用换行符创建匹配,并在替换中使用对该匹配的反向引用的想法。
  3. 在内容中,可能会出现多行换行符。但是,在这种情况下,我们不想对它们进行分组,因为代码的其余部分将将它们视为不同类型的换行符。这就是为什么换行符列表在匹配的反向引用中显式地声明。
票数 4
EN

Stack Overflow用户

发布于 2013-11-14 12:24:04

根据欧哈尔的回答。

这可以为LF、CR+LF等EOL返回一两个字符。

代码语言:javascript
运行
复制
  $eols = array_count_values(str_split(preg_replace("/[^\r\n]/", "", $string)));
  $eola = array_keys($eols, max($eols));
  $eol = implode("", $eola);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11066857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档