string - 如何找到一个被剥离非 ASCII 字符的字符串副本

标签 string postgresql non-ascii-characters

我有一个书名表 - 大多数书名都重复多次以用于不同的版本。许多标题在导入时错误地缺少了非 ASCII 字符,例如,“La métamorphose”变成了“La m?tamorphose”,有时 é 变成了空格,或者只是从字符串中删除了。

表格

editionid | bookid | title
--------------------------------------------
1         | 1      | Elementarne čestice
2         | 1      | Elementarne ?estice
3         | 1      | Elementarne estice
4         | 1      | Las partículas elementales
5         | 2      | Schöne neue Welt
6         | 2      | Sch ne neue Welt

我想通过去除标题的非 ASCII 码并与同一本书的其他标题进行比较来识别不正确的标题。如果有匹配,我发现标题有问题。

结果:

o.title (flawed)    | e.title (good)
-----------------------------------
Elementarne ?estice | Elementarne čestice
Elementarne estice  | Elementarne čestice
Sch ne neue Welt    | Schöne neue Welt

该表相当大,但因为我只需要在性能不是关键的情况下执行此操作。

我的方法:

select distinct on (o.editionid) o.title, e.title
from editions o
inner join editions e on (o.bookid = e.bookid)
where o.bookid between 1 and 1000
    and e.title !~ '^[ -~]*$' -- only for performance
    and ((
      e.title like '%Þ%' and (o.title = regexp_replace(e.title, '[Þ]', '?') or o.title = regexp_replace(e.title, '[Þ]', ' ') or o.title = regexp_replace(e.title, '[Þ]', ''))
    ) or (
      e.title like '%ß%' and (o.title = regexp_replace(e.title, '[ß]', '?') or o.title = regexp_replace(e.title, '[ß]', ' ') or o.title = regexp_replace(e.title, '[ß]', ''))
    ) or (
      e.title like '%à%' and (o.title = regexp_replace(e.title, '[à]', '?') or o.title = regexp_replace(e.title, '[à]', ' ') or o.title = regexp_replace(e.title, '[à]', ''))
    .
    .
    .
    ))

到目前为止,这是可行的,但似乎不可能单独添加所有非 ASCII 字符。有没有人知道一次涵盖所有非 ASCII 字符的更通用的方法?

其次 - 如果两个不同的字符被剥离,它就不起作用,我不知道如何解决。

第三,但也许是不可能的 - 通常只有一些非 ASCII 被转换,但不是全部,即“Weiße Nächte”变成了“Wei e Nächte” - 如果这些也能被覆盖,那就太好了。

最佳答案

经过一些摆弄,最终并没有那么难:

select distinct on (o.editionid) o.title as flawed, e.title as good
from editions o
inner join editions e on (o.bookid = e.bookid)
where o.bookid between 0 and 10000
    and e.title ~ '[^\x00-\x7F]'
    and (
            o.title = regexp_replace(e.title, '[^\x00-\x7F]', '?', 'g') 
            or o.title = regexp_replace(e.title, '[^\x00-\x7F]', ' ', 'g')
        )

regexp_replace(e.title, '[^\x00-\x7F]', '?', 'g')\x00-\x7F 的键> 都是不在 ASCII 方案中的 Unicode 字符,并且 'g' 不断搜索同一字符串中的更多匹配项。

关于string - 如何找到一个被剥离非 ASCII 字符的字符串副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45589171/

相关文章:

Java 检查 String 中的 int 范围

ruby - 在 Ruby 中,您可以对从文件中读取的数据执行字符串插值吗?

SQL 查询在 postgresql 数据库中不能正常工作

database - Postgres 中的数千张表 - 一种反模式?

python - 对具有无效 ASCII 的字符串进行 title() 方法

java - 字符串与字符的串联在 Java 中如何工作?

c# - 检查一个字符串是否是回文

sql - 对每页限制的分组查询结果进行分页

Python 正则表达式匹配非 ascii 名称

python - 检测单词中的重音(Python)