我正在从一个导入一些数据 CSV 文件,以及大于的数字 1000 变成 1,100 ETC。

有什么好方法可以从中删除引号和逗号,以便我可以将其放入 int 场地?

编辑:

数据实际上已经在 MySQL 表中,所以我需要能够使用 SQL 来完成此操作。抱歉混淆了。

有帮助吗?

解决方案

这是正则表达式的一个很好的例子。您可以在导入之前(更容易)或稍后(如果 SQL 导入接受这些字符)对数据运行查找和替换(不太容易)。但无论哪种情况,您都可以使用多种方法来进行查找和替换,无论是编辑器、脚本语言、GUI 程序等。请记住,您需要查找并替换 全部 的坏角色。

查找逗号和引号(假设只有双引号)的典型正则表达式是: (黑名单)

/[,"]/

或者,如果您发现将来可能会发生变化,则此正则表达式会匹配除数字或小数点之外的任何内容。 (白名单)

/[^0-9\.]/

上面的人讨论的是我们不知道您的 CSV 文件中的所有数据。听起来您想从 CSV 文件中的所有数字中删除逗号和引号。但由于我们不知道 CSV 文件中还包含哪些内容,因此我们希望确保不会损坏其他数据。只是盲目地进行查找/替换可能会影响文件的其他部分。

其他提示

我的猜测是,因为数据能够导入,所以该字段实际上是 varchar 或某些字符字段,因为导入到数字字段可能会失败。这是我纯粹运行 MySQL、SQL 解决方案的测试用例。

  1. 该表只是一个 varchar 列 (alpha)。

    mysql> desc t;
    
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | alpha | varchar(15) | YES  |     | NULL    |       | 
    +-------+-------------+------+-----+---------+-------+
    
  2. 添加一条记录

    mysql> insert into t values('"1,000,000"');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t;
    
    +-------------+
    | alpha       |
    +-------------+
    | "1,000,000" | 
    +-------------+
    
  3. 更新声明。

    mysql> update t set alpha = replace( replace(alpha, ',', ''), '"', '' );
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from t;
    
    +---------+
    | alpha   |
    +---------+
    | 1000000 | 
    +---------+
    

所以最后我使用的语句是:

UPDATE table
   SET field_name = replace( replace(field_name, ',', ''), '"', '' );

我看了看 MySQL 文档 看起来我无法找到正则表达式 并替换. 。虽然你可以,比如 埃尔迪拉, ,使用正则表达式进行查找,然后使用替代解决方案进行替换。


还要小心 s/"(\d+),(\d+)"/$1$2/ 因为如果数字不止一个逗号怎么办,例如“1,000,000”,您将需要进行全局替换(在 perl 中是 s///g)。但即使使用全局替换,替换也会从上次停止的地方开始(除非 perl 不同),并且会错过所有其他逗号分隔的组。一个可能的解决方案是使第一个 (\d+) 可选,如下所示 s/(\d+)?,(\d+)/$1$2/g 在这种情况下,我需要第二次查找和替换来删除引号。

下面是一些仅作用于字符串“1,000,000”的正则表达式的 ruby​​ 示例,请注意字符串内没有双引号,这只是数字本身的字符串。

>> "1,000,000".sub( /(\d+),(\d+)/, '\1\2' )
# => "1000,000"  
>> "1,000,000".gsub( /(\d+),(\d+)/, '\1\2' )
# => "1000,000"  
>> "1,000,000".gsub( /(\d+)?,(\d+)/, '\1\2' )
# => "1000000"  
>> "1,000,000".gsub( /[,"]/, '' )
# => "1000000"  
>> "1,000,000".gsub( /[^0-9]/, '' )
# => "1000000"

您可以使用这个 perl 命令。

Perl -lne 's/[,|"]//; print' file.txt > newfile.txt

您可能需要稍微尝试一下,但它应该可以解决问题。

这是 PHP 的方式:

$stripped = str_replace(array(',', '"'), '', $value);

链接到 W3Schools 页面

事实上,nlucaroni,你的情况不太正确。您的示例不包含双引号,因此

id,age,name,...
1,23,phil,

与我的正则表达式不匹配。它需要格式“XXX,XXX”。我想不出什么时候它会错误匹配的例子。

以下所有示例都不会在正则表达式中包含分隔符:

"111,111",234
234,"111,111"
"111,111","111,111"

如果您能想到一个反例,请告诉我。

干杯!

改了题的解法基本是一样的。

您必须使用正则表达式 where 子句运行选择查询。

类似的东西

Select *
  FROM SOMETABLE
  WHERE SOMEFIELD REGEXP '"(\d+),(\d+)"'

对于这些行中的每一行,您需要执行以下正则表达式替换 s/"(\d+),(\d+)"/$1$2/,然后使用新值更新字段。

请 Joseph Pecoraro 认真对待,并在对任何文件或数据库进行大量更改之前进行备份。因为每当您执行正则表达式时,如果您错过了某些情况,则可能会严重弄乱数据。

我的命令确实删除了所有 ',' 和 '"'。

为了更严格地转换字符串“1,000”,您将需要以下命令。

Perl -lne 's/"(\d+),(\d+)"/$1$2/; print' file.txt > newfile.txt

丹尼尔和埃尔迪拉的回答有一个问题:他们删除整个文件中的所有引号和逗号。

当我必须做这样的事情时,我通常要做的就是首先用制表符替换所有分隔引号和(通常)分号。

  • 搜索: ";"
  • 代替:

因为我知道受影响的值将在哪一列中,所以我会进行另一次搜索并替换:

  • 搜索: ^([ ]+) ([ ]+) ([0-9]+),([0-9]+)
  • 代替: \1 \2 \3\4

...给定带逗号的值位于第三列。

您需要以“^”开头,以确保它从行首开始。然后,您重复 ([0-9]+) 的次数与您只想保留原样的列的次数相同。

([0-9]+),([0-9]+) 搜索包含数字、逗号和另一个数字的值。

在替换字符串中,我们使用 \1 和 \2 来保留编辑行中的值,并用 (制表符)分隔它们。然后我们输入 \3\4 (中间没有制表符),将数字的两个组成部分(不带逗号)放在一起。之后的所有值都将被保留。

如果您需要文件用分号来分隔元素,则可以继续用分号替换制表符。但是,如果您省略引号,则必须确保文本值本身不包含任何分号。这就是为什么我更喜欢使用 TAB 作为列分隔符。

我通常在支持 RegExp 的普通文本编辑器 (EditPlus) 中执行此操作,但相同的正则表达式可以在任何编程语言中使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top