博主头像
御坂誉

Vertin - Misaka Foundation

头图

Mathematica!

写两个东西,一是Mathematica的字符串差异分析,二是批处理。后面还有一个比较长的Mathematica文本库构建和管理打算单独写一篇。


字符串差异分析

问题的背景是,前两天给网站加了APlayer,然后APlayer的字体和颜色和主题很不搭,所以想改一下APlayer.min.css。改完之后想确认一下改了哪些部分,因为APlayer.min.css整个文件所有内容都在一行里,所以用WinMerge和Git都不太顺手。因此想着用Mathematica写一个能做字符串比较的东西。

先把两个CSS文件作为文本(Text)导入进来

i = Import[file, "Text"];
j = Import[file, "Text"];

然后用内建的SequenceAlignment比较差异

d = SequenceAlignment[i, j, Method -> "Local"];

SequenceAlignment的作用是

In[1] := SequenceAlignment["abcXXabcXabc", "abcabcYYYabc"]
Out[1] := {"abc", {"XX", ""}, "abc", {"X", "YYY"}, "abc"}
In[2] := SequenceAlignment["abcXXabcXabc", "abcabcYYYabc", Method -> "Local"]
Out[2] := {{"abcXX", ""}, "abc", {"X", ""}, "abc", {"", "YYYabc"}}

这个结果的解读方式是

{"abc", {"XX", ""}, "abc", {"X", "YYY"}, "abc"}
   ↑      ↑           ↑      ↑             ↑      <-第一个文本
   ↑           ↑      ↑            ↑       ↑      <-第二个文本
{{"abcXX", ""}, "abc", {"X", ""}, "abc", {"", "YYYabc"}}
     ↑            ↑      ↑          ↑     ↑       <-第一个文本
           ↑      ↑           ↑     ↑          ↑  <-第二个文本

Method -> "Local"感觉就是让结果的“块”更整体一点。当然这种括号嵌套的结果表示方式非常难阅读,特别是文本很长的时候,所以我们可以给差异内容染色,使用

coloredDiff = 
  Style[#, 
     Piecewise[{{FontColor -> Red, Length@# != 0}}, 
      FontColor -> Black]] & /@ d;

这里我们利用差异项都是长度为2的列表(比如之前的{"X", ""}),而一样的项都是长度为0的列表(比如"abc")。因此我们定义一个分段函数,它在列表长度不为0时取FontColor -> Red,为0时取FontColor -> Black,然后把这个Style连同分段函数逐项作用于结果列表上。效果如下

微信截图_20241125122327.webp
微信截图_20241125122327.webp

这样就可以看到,我改了字体和背景颜色,然后把border-bottom删掉了之类的。


批处理(以批量格式转换为例)

这个问题的背景是,想要把图片批量转成webp来缩小网页体积。

首先我们用SetDirectory["path"]设定当前工作目录,这样可以免去每次都要输路径的麻烦,然后使用

imageList = 
  Select[FileNames[], MemberQ[{"jpg", "png"}, FileExtension[#]] &];

来读取所有扩展名为jpg和png的文件,FileNames[]会返回当前目录下所有文件文件名的列表,然后Select在这个列表里选出所有FileExtension含在{"jpg", "png"}中的文件构成的子列。

接下来对于得到的子列中的每个文件有

process = 
  Function[path, 
   Export[FileBaseName[path] <> ".webp", Import@path, 
    CompressionLevel -> 0.5]; DeleteFile[path]];

其中我们用FileBaseName取出不带扩展名的文件名,然后添加扩展名".webp",这样就得到了输出的文件名。我们用Import导入对应的图片文件,然后CompressionLevel对它进行压缩,这个得到的结果被当作Export的输入,并被输入到前面的输出文件名中。接着DeleteFile删除原始文件。

最后我们只需要运行就可以了。

Parallelize[process /@ imageList];

Mathematica!
https://misaka-yu.com/archives/124/
本文作者 vertinme
发布时间 2024-11-25
许可协议 CC BY-NC-SA 4.0
发表新评论