Board logo

标题: [文本处理] [已解决]如何能打开文件时自动识别编码处理后保存为ANSI? [打印本页]

作者: xp3000    时间: 2023-1-2 09:46     标题: [已解决]如何能打开文件时自动识别编码处理后保存为ANSI?

本帖最后由 xp3000 于 2023-1-8 08:33 编辑

一些txt文件,里面很多多余内容需要删除,例如
PS:……
PS2:……
PS3:……
最后需要保存为ANSI编码。
搜索到一个这个不知道怎么用
  1. function detectEncoding(str) {
  2.   // 检查字符串开头的 BOM
  3.   if (str.charCodeAt(0) === 0xFEFF) {
  4.     return 'UTF-16BE';
  5.   } else if (str.charCodeAt(0) === 0xFFFE) {
  6.     return 'UTF-16LE';
  7.   } else if (str.charCodeAt(0) === 0xEFBB && str.charCodeAt(1) === 0xBF) {
  8.     return 'UTF-8BOM';
  9.   }
  10.   // 检查字符串开头的“UTF-32”标识符
  11.   if (str.charCodeAt(0) === 0x0000 && str.charCodeAt(1) === 0x0000 && str.charCodeAt(2) === 0xFEFF) {
  12.     return 'UTF-32BE';
  13.   } else if (str.charCodeAt(0) === 0xFEFF && str.charCodeAt(1) === 0x0000 && str.charCodeAt(2) === 0x0000) {
  14.     return 'UTF-32LE';
  15.   }
  16.   // 如果未找到上述模式,则假定字符串以 ASCII 或 ANSI 编码
  17.   return 'ANSI/ASCII';
  18. }
复制代码
  1. To determine the character encoding of a string in JavaScript, you can use the .charCodeAt() method to get the numeric Unicode representation of each character in the string and then use some logic to determine the character encoding based on the values that are returned.
  2. For example, to determine if a string is encoded in ANSI, you could use the following approach:
  3. Copy code
  4. function isANSI(str) {
  5.   for (let i = 0; i < str.length; i++) {
  6.     // If any character has a Unicode value greater than 255,
  7.     // the string is not encoded in ANSI
  8.     if (str.charCodeAt(i) > 255) return false;
  9.   }
  10.   // If all characters have a Unicode value less than or equal to 255,
  11.   // the string is encoded in ANSI
  12.   return true;
  13. }
  14. To determine if a string is encoded in UTF-8, you could use the following approach:
  15. Copy code
  16. function isUTF8(str) {
  17.   for (let i = 0; i < str.length; i++) {
  18.     let c = str.charCodeAt(i);
  19.     // If the Unicode value of the character is in the range 0-127,
  20.     // it is encoded as a single byte in UTF-8
  21.     if (c >= 0 && c <= 127) continue;
  22.     // If the Unicode value of the character is in the range 128-2047,
  23.     // it is encoded as two bytes in UTF-8
  24.     if (c >= 128 && c <= 2047) {
  25.       i++;
  26.       continue;
  27.     }
  28.     // If the Unicode value of the character is in the range 2048-65535,
  29.     // it is encoded as three bytes in UTF-8
  30.     if (c >= 2048 && c <= 65535) {
  31.       i += 2;
  32.       continue;
  33.     }
  34.     // If the Unicode value of the character is in the range 65536-1114111,
  35.     // it is encoded as four bytes in UTF-8
  36.     if (c >= 65536 && c <= 1114111) {
  37.       i += 3;
  38.       continue;
  39.     }
  40.     // If the character is not encoded as a single, double, triple, or
  41.     // quadruple byte in UTF-8, the string is not encoded in UTF-8
  42.     return false;
  43.   }
  44.   // If all characters in the string are encoded as a single, double,
  45.   // triple, or quadruple byte in UTF-8, the string is encoded in UTF-8
  46.   return true;
  47. }
  48. To determine if a string is encoded in UTF-8 with a BOM (Byte Order Mark), you could use the following approach:
  49. Copy code
  50. function isUTF8BOM(str) {
  51.   // The BOM for UTF-8 is the byte sequence EF BB BF
  52.   if (str.charCodeAt(0) === 0xEF && str.charCodeAt(1) === 0xBB && str.charCodeAt(2) === 0xBF) {
  53.     // If the first three bytes of the string match the BOM for UTF-8,
  54.     // check if the rest of the string is encoded in UTF-8
  55.     return isUTF8(str.substring(3));
  56.   }
  57.   // If the first three bytes of the string do not match the BOM for UTF-8,
  58.   // the string is not encoded in UTF-8
  59. Try again
复制代码

作者: czjt1234    时间: 2023-1-2 20:00

原文件能确定都是啥编码吗?
全部unicode,还是全部utf-8,还是全部ANSI,还是各种都有?
作者: xp3000    时间: 2023-1-2 20:28

各种编码都有,可能还有UTF-32,文件被人上传会删除空行,网站处理后我下载的是正常和乱码的混合文本
作者: czjt1234    时间: 2023-1-2 22:10

其他的都好处理,utf-32编码的不知道怎么读取
作者: czjt1234    时间: 2023-1-2 22:31

utf-32文件你是用啥软件打开的?
发个utf-32文件来看看
作者: xp3000    时间: 2023-1-2 22:52

\x2B\x2F\x76        文件为 UTF-7 编码
\xEF\xBB\xBF        文件为 UTF-8 BOM 编码
\xFE\xFF        文件为 UTF-16 BE 编码
\xFF\xFE        文件为 UTF-16 LE 编码
\x00\x00\xFE\xFF        文件为 UTF-32 BE 编码
\xFF\xFE\x00\x00        文件为 UTF-32 LE 编码

不能上传文件,查了下文件开头这样的,以二进制十六进制查看文件,开头是上面去掉\x内容
作者: hlzj88    时间: 2023-1-2 23:19

  1. findstr /i "的" 1.txt&&goto wc || @iconv -c -f utf-8 -t GBK 1.txt>>gb1.txt
  2. findstr /i "的" gb1.txt&&move /y gb1.txt 1.txt&&goto wc || @iconv -c -f utf-32 -t GBK 1.txt>>gb2.txt
  3. findstr /i "的" gb2.txt&&move /y gb2.txt 1.txt&&goto wc || @iconv -c -f UCS-2LE -t GBK 1.txt>>gb3.txt
  4. findstr /i "的" gb3.txt&&move /y gb3.txt 1.txt
  5. :wc
  6. del /q gb*.txt
  7. echo 完成
  8. findstr /iv "ps2 ps3 ps" 1.txt>>2.txt
  9. pause
复制代码
http://bcn.bathome.net/s/tool/index.html?key=iconv

这是一个文件处理的苯办法,utf-8 和unicode 测试都成功。utf-32,软件iconv是支持的,但我没有这样的文件,也不会保存为这样的文件。所以这个只是臆测写了。

其他什么格式的文件,不知道还能有什么格式,所以没有多写。  查找  的  字的目的是中文的字的字频最高。处理英文可以用 the
作者: WHY    时间: 2023-1-2 23:41

本帖最后由 WHY 于 2023-1-3 14:15 编辑

Test.ps1,右键使用PowerShell运行,增加 utf-7 编码识别
  1. function Get-Encoding($filePath){
  2.     $reg = '[\xC0-\xDF](?:[^\x80-\xBF]|$)';
  3.     $reg += '|[\xE0-\xEF].{0,1}(?:[^\x80-\xBF]|$)';
  4.     $reg += '|[\xF0-\xF7].{0,2}(?:[^\x80-\xBF]|$)';
  5.     $reg += '|[\xF8-\xFB].{0,3}(?:[^\x80-\xBF]|$)';
  6.     $reg += '|[\xFC-\xFD].{0,4}(?:[^\x80-\xBF]|$)';
  7.     $reg += '|[\xFE-\xFE].{0,5}(?:[^\x80-\xBF]|$)';
  8.     $reg += '|[\x00-\x7F][\x80-\xBF]';
  9.     $reg += '|[\xC0-\xDF].[\x80-\xBF]';
  10.     $reg += '|[\xE0-\xEF]..[\x80-\xBF]';
  11.     $reg += '|[\xF0-\xF7]...[\x80-\xBF]';
  12.     $reg += '|[\xF8-\xFB]....[\x80-\xBF]';
  13.     $reg += '|[\xFC-\xFD].....[\x80-\xBF]';
  14.     $reg += '|[\xFE-\xFE]......[\x80-\xBF]';
  15.     $reg += '|^[\x80-\xBF]';
  16.     $byte = [IO.File]::ReadAllBytes($filePath);
  17.     $BOM  = [BitConverter]::ToString($byte[0..3]);
  18.     If ($BOM -eq 'FF-FE-00-00'){
  19.         return (New-Object System.Text.UTf32Encoding $false, $true); #UTF32LE with BOM
  20.     } elseIf ($BOM -eq '00-00-FE-FF'){
  21.         return (New-Object System.Text.UTf32Encoding $true, $true);  #UTF32BE with BOM
  22.     } elseIf ($BOM.StartsWith('FF-FE') -or $BOM.StartsWith('FE-FF')){
  23.         return [Text.Encoding]::GetEncoding('UNICODE');              #UTF16 with BOM
  24.     } elseIf ($BOM.StartsWith('EF-BB-BF')){
  25.         return [Text.Encoding]::GetEncoding('UTF-8');                #UTF8 with BOM
  26.     } elseIf ($BOM.StartsWith('2B-2F-76')){
  27.         return [Text.Encoding]::GetEncoding('UTF-7');                #UTF7 with BOM
  28.     } else {
  29.         $m = [regex]::Match([char[]]$byte -join '', $reg);
  30.         If ($m.Success){
  31.             return [Text.Encoding]::GetEncoding('GB2312');           #ANSI
  32.         } else {
  33.             return [Text.Encoding]::GetEncoding('UTF-8');            #UTF8 without BOM
  34.         }
  35.     }
  36. }
  37. $path = $MyInvocation.MyCommand.Path -replace '\\[^\\]*$', '\';     #脚本自身路径
  38. $dstFolder = $path + 'Result\';                                     #目标文件路径
  39. if(![IO.Directory]::Exists($dstFolder)){$null = md $dstFolder};     #创建目标目录
  40. forEach( $file In (dir -Literal $path -Filter *.txt) ){
  41.     $enc = Get-Encoding $file.FullName;                             #获取编码
  42.     $arr = [IO.File]::ReadAllLines($file.FullName, $enc);
  43.     $arr = $arr -NotMatch 'PS[0-9]*:';   #删除包含 'PS' + 数字 + ':'的行
  44.     #另存为ansi编码
  45.     [IO.File]::WriteAllLines($dstFolder + $file.Name, $arr, [Text.Encoding]::GetEncoding('GB2312'));
  46. }
  47. echo 'Done';
  48. [Console]::ReadLine();
复制代码

作者: hlzj88    时间: 2023-1-2 23:57

回复 8# WHY

非常牛
作者: czjt1234    时间: 2023-1-3 07:06

回复 6# xp3000


   你有空用百度网盘上传一个文件,分享个链接
我想看看utf-32文件啥模样,notepad++是不支持的
作者: xp3000    时间: 2023-1-3 09:18

本帖最后由 xp3000 于 2023-1-3 09:20 编辑

回复 10# czjt1234
https://cowtransfer.com/s/215a0b55e04c4e 点击链接查看 [ UTF-32.zip ] ,或访问奶牛快传 cowtransfer.com 输入传输口令 mdty5z 查看;
作者: xp3000    时间: 2023-1-3 09:21

这个BAT+JS可以实现吗
作者: czjt1234    时间: 2023-1-3 10:35

回复 12# xp3000


   为什么要js,我测试了一下你发的文件,vbs可以实现
作者: xp3000    时间: 2023-1-3 11:01

vbs也可以,主要是js能看懂一点
作者: czjt1234    时间: 2023-1-3 15:46

回复 14# xp3000


   这样啊,那就算了,vbs没有读写utf32编码的com对象,要读取二进制数据然后逐个解码,太繁了
作者: WHY    时间: 2023-1-6 21:03

我贴一个VBS
  1. On Error ReSume Next
  2. Dim fso, myDir, dstFolder
  3. Set fso = CreateObject("Scripting.FileSystemObject")
  4. myDir = fso.GetFile(WSH.ScriptFullName).ParentFolder.Path           '脚本自身目录
  5. dstFolder = myDir & "\Result"                                       '目标目录
  6. If Not fso.FolderExists(dstFolder) Then fso.CreateFolder(dstFolder) '创建目标目录
  7. Dim objFile
  8. For Each objFile In fso.GetFolder(myDir).Files
  9.     If LCase(Right(objFile.Name, 4)) = ".txt" Then
  10.         If objFile.Size > 0 Then
  11.             CheckEncoding objFile.Path, dstFolder & "\" & objFile.Name
  12.         End If
  13.     End If
  14. Next
  15. Function DeleteStr(ByRef str)
  16.     Dim reg, arrIn, n, i, arrOut()
  17.     Set reg = New RegExp
  18.     reg.IgnoreCase = True
  19.     reg.Pattern = "PS[0-9]*:"      '删除包含 "PS" + 数字 + ":"的行
  20.     str = Replace(str, vbCrLf, vbLf)
  21.     arrIn = Split(str, vbLf)
  22.     n = 0
  23.     For i = 0 To UBound(arrIn)
  24.         If Not reg.Test(arrIn(i)) Then
  25.             ReDim PreServe arrOut(n)
  26.             arrOut(n) = arrIn(i)
  27.             n = n + 1
  28.         End If
  29.     Next
  30.     DeleteStr = Join(arrOut, vbCrLf)
  31. End Function
  32. Function ConvertUtf32ToUtf16(srcFile, dstFile, encName)
  33.     Dim xmlDoc, node
  34.     Set xmlDoc = CreateObject("MSXML2.DOMDocument")
  35.     Set node = xmlDoc.CreateElement("binary")
  36.     node.DataType = "bin.hex"
  37.     Dim ado, sz, i, j, arr()
  38.     Set ado = CreateObject("ADODB.Stream")
  39.     ado.Type = 1
  40.     ado.Open
  41.     ado.LoadFromFile srcFile
  42.     sz = ado.Size
  43.     ReDim arr(sz\4)
  44.     Dim h(3)
  45.     For i = 1 To sz Step 4
  46.         For j = 0 To 3
  47.             h(j) = Right("00" & Hex(AscB(ado.Read(1))), 2)
  48.         Next
  49.         If encName = "UTF32LE" Then
  50.             arr(i\4) = h(0) & h(1)
  51.         ElseIf encName = "UTF32BE" Then
  52.             arr(i\4) = h(2) & h(3)
  53.         End If
  54.     Next
  55.     node.Text = Join(arr, "")
  56.     ado.Position = 0
  57.     ado.Write node.NodeTypedValue
  58.     ado.SetEOS()
  59.     ado.SaveToFile dstFile, 2
  60.     ado.Close()
  61.     SaveFileUtf16ToAnsi dstFile, dstFile
  62. End Function
  63. Function SaveFileUtf16ToAnsi(srcFile, dstFile)
  64.     Dim f, str
  65.     Set f = fso.OpenTextFile(srcFile, 1, True, -1)
  66.     str = DeleteStr(f.ReadAll)
  67.     f.Close
  68.     fso.OpenTextFile(dstFile, 2, True).Write(str)
  69. End Function
  70. Function SaveFileUtf8ToAnsi(srcFile, dstFile, charset)
  71.     Dim ado, str
  72.     Set ado = CreateObject("ADODB.Stream")
  73.     ado.Type = 2
  74.     ado.CharSet = charset
  75.     ado.Open
  76.     ado.LoadFromFile srcFile
  77.     str = ado.ReadText(-1)
  78.     ado.Position = 0
  79.     ado.CharSet = "GB2312"
  80.     ado.WriteText DeleteStr(str)
  81.     ado.SetEOS
  82.     ado.SaveToFile dstFile, 2
  83.     ado.Close
  84. End Function
  85. Function SaveFileAnsiToAnsi(srcFile, dstFile)
  86.     Dim f, str
  87.     Set f = fso.OpenTextFile(srcFile, 1, True)
  88.     str = DeleteStr(f.ReadAll)
  89.     f.Close
  90.     fso.OpenTextFile(dstFile, 2, True).Write(str)
  91. End Function
  92. Function CheckEncoding(srcFile, dstFile)
  93.     Dim ado, i, BOM
  94.     Set ado = CreateObject("ADODB.Stream")
  95.     ado.Type = 1
  96.     ado.Open
  97.     ado.LoadFromFile srcFile
  98.     For i = 0 To 3
  99.         BOM = BOM & Right("00" & Hex(AscB(ado.Read(1))), 2)
  100.     Next
  101.     If BOM = "FFFE0000" Then
  102.         ado.Close
  103.         ConvertUtf32ToUtf16 srcFile, dstFile, "UTF32LE"
  104.     ElseIf BOM = "0000FEFF" Then
  105.         ado.Close
  106.         ConvertUtf32ToUtf16 srcFile, dstFile, "UTF32BE"
  107.     ElseIf Left(BOM, 4) = "FFFE" or Left(BOM, 4) = "FEFF" Then
  108.         ado.Close
  109.         SaveFileUtf16ToAnsi srcFile, dstFile   'UNICODE
  110.     ElseIf Left(BOM, 6) = "EFBBBF" Then
  111.         ado.Close
  112.         SaveFileUtf8ToAnsi srcFile, dstFile, "UTF-8"
  113.     ElseIf Left(BOM, 6) = "2B2F76" Then
  114.         ado.Close
  115.         SaveFileUtf8ToAnsi srcFile, dstFile, "UTF-7"
  116.     Else
  117.         Dim sz, arr()
  118.         ado.Position = 0
  119.         sz = ado.Size
  120.         ReDim arr(sz-1)
  121.         For i = 1 To sz
  122.             arr(i-1) = ChrW(AscB(ado.Read(1)))
  123.         Next
  124.         If isUTF8(arr) Then
  125.             ado.Close
  126.             SaveFileUtf8ToAnsi srcFile, dstFile, "UTF-8"
  127.         Else
  128.             ado.Close
  129.             SaveFileAnsiToAnsi srcFile, dstFile  'ANSI
  130.         End If
  131.     End If
  132. End Function
  133. Function isUTF8(ByRef arr)
  134.     Dim s, reg
  135.     s = "[\xC0-\xDF](?:[^\x80-\xBF]|$)"
  136.     s = s & "|[\xE0-\xEF].{0,1}(?:[^\x80-\xBF]|$)"
  137.     s = s & "|[\xF0-\xF7].{0,2}(?:[^\x80-\xBF]|$)"
  138.     s = s & "|[\xF8-\xFB].{0,3}(?:[^\x80-\xBF]|$)"
  139.     s = s & "|[\xFC-\xFD].{0,4}(?:[^\x80-\xBF]|$)"
  140.     s = s & "|[\xFE-\xFE].{0,5}(?:[^\x80-\xBF]|$)"
  141.     s = s & "|[\x00-\x7F][\x80-\xBF]"
  142.     s = s & "|[\xC0-\xDF].[\x80-\xBF]"
  143.     s = s & "|[\xE0-\xEF]..[\x80-\xBF]"
  144.     s = s & "|[\xF0-\xF7]...[\x80-\xBF]"
  145.     s = s & "|[\xF8-\xFB]....[\x80-\xBF]"
  146.     s = s & "|[\xFC-\xFD].....[\x80-\xBF]"
  147.     s = s & "|[\xFE-\xFE]......[\x80-\xBF]"
  148.     s = s & "|^[\x80-\xBF]"
  149.     Set reg = New RegExp
  150.     reg.Pattern = s
  151.     isUTF8 = Not reg.Test(Join(arr, ""))
  152. End Function
  153. MsgBox "Done"
复制代码

作者: czjt1234    时间: 2023-1-6 22:27

回复 16# WHY


   所以说很烦

保存备用
作者: terse    时间: 2023-1-7 19:00

发一个js的  先粗暴处理32编码文件
  1. 1>1/* :
  2. @echo off
  3. set "ph=%cd%\Result\"
  4. set "enc=gb2312"
  5. md "%ph%" 2>nul
  6. dir /b /a-d *.txt *.jpg| cscript -nologo -e:jscript %0 "%ph%" "%enc%"
  7. pause & exit
  8. */
  9. var cp1252 = "\u20AC\u0081\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\u008D\u017D\u008F\u0090\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\u009D\u017E\u0178";
  10. var reg = /^(fffe00|00feff|efbbbf|fffe|feff)/i, re = /(?:^|\n)(PS\d*:.*)/g,
  11. charsets = { 'fffe00' : 'unicodefffe', '00feff' : 'unicodefeff', 'efbbbf' : "UTF-8",  'fffe' : 'unicodefffe', 'feff' : 'unicodefeff' };
  12. function getText(file, enc) {
  13.        var i = 0, stream, bin, count, content, hex='';
  14.        stream = new ActiveXObject("ADODB.Stream");
  15.        stream.type = 2;
  16.        stream.charset = 'Latin1';
  17.        stream.open();
  18.        stream.loadFromFile(file);
  19.        bin= stream.ReadText(-1);
  20.        count = (bin.length > 4096) ? 4096 : bin.length;
  21.        for (;i<4;) hex += bin.charCodeAt(i++).toString(16);
  22.        var bom = reg.test(hex) ? hex.match(reg)[0] : '';
  23.        stream.Position = 0;
  24.        stream.Type = 2;
  25.        stream.charset = bom ? charsets[bom] : getEncoding(bin, count) ? 'UTF-8' : 'gbk';
  26.        content = stream.readText(-1);
  27.        if (/00/.test(bom))
  28.        {
  29.             if (bom == '00feff') { content = content.slice(2) };
  30.             content = content.replace(/\x00/g, '');
  31.        }
  32.        stream.Close
  33.        return content
  34. }
  35. function getEncoding(b, len) {
  36.        var n = 1;
  37.        for ( var i = 0; i < len; i++)
  38.        {
  39.                var byt = (b.charCodeAt(i) <= 255) ? b.charCodeAt(i):
  40.                      128+cp1252.indexOf(b.charAt(i));
  41.                if (n == 1)
  42.                {
  43.                       if (byt >= 0x80)
  44.                       {
  45.                           while (((byt <<= 1) & 0x80) != 0) {n++}
  46.                           if (n == 1 || n > 6) { return false }
  47.                       }
  48.                } else {
  49.                    if ((byt & 0xC0) != 0x80) { return false}
  50.                    n--;
  51.                }
  52.        }
  53.        return true;
  54. }
  55. var enc = WScript.Arguments(1);
  56. while (!WScript.StdIn.AtEndOfStream){
  57.        var file = WScript.StdIn.ReadLine();
  58.        var text = getText( file ).replace(re, '');
  59.        var path = WScript.Arguments(0) + file;
  60.        var stream = new ActiveXObject("ADODB.Stream");
  61.        stream.type = 2;
  62.        stream.charset = enc;
  63.        stream.open();
  64.        stream.writetext(text);
  65.        stream.SaveToFile(path, 2);
  66.        stream.Close
  67. }
复制代码

作者: xp3000    时间: 2023-1-8 09:47

学习了,谢谢各位大神




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2