从MySQL中的字符串中删除引号和逗号

时间:2020-03-05 18:38:59  来源:igfitidea点击:

我正在从CSV文件中导入一些数据,大于1000的数字会变成1100。

从中删除引号和逗号的一种好方法是什么,这样我可以将其放入int字段中?

编辑:

数据实际上已经在MySQL表中,因此我需要能够使用SQL。对不起,混淆了。

解决方案

回答

我们可以使用此perl命令。

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

我们可能需要尝试一下,但是它可以解决问题。

回答

这是PHP的方式:

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

链接到W3Schools页面

回答

Daniel和Eldila的回答有一个问题:他们删除了整个文件中的所有引号和逗号。

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

  • 搜索: ";"
  • 替换:\ t

由于我知道受影响的值将在哪一列中,因此我再次进行搜索并替换:

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

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

我们需要以" ^"开头,以确保它从行首开始。然后,我们重复([0-9] +)\ t的次数就是我们想保留的原样。

([[0-9] +),([0-9] +)在存在数字,逗号和另一个数字的位置搜索值。

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

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

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

回答

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

为了更严格地转换字符串" 1,000",我们将需要以下命令。

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

回答

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

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

与我的正则表达式不匹配。它要求格式为" XXX,XXX"。我想不出何时匹配不正确的示例。

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

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

如果我们能想到反例,请告诉我。

干杯!

回答

这是正则表达式的一个很好的例子。我们可以在导入之前(更轻松)或者稍后(如果SQL导入接受了这些字符)对数据进行查找和替换,(不太容易)。但无论哪种情况,我们都可以使用多种方法来查找和替换,包括编辑器,脚本语言,GUI程序等。请记住,我们将要查找并替换所有不良字符。

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

/[,"]/

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

/[^0-9\.]/

上面的人讨论的是,我们不知道我们CSV文件中的所有数据。听起来我们想从CSV文件中的所有数字中删除逗号和引号。但是因为我们不知道CSV文件中还有什么,所以我们要确保我们不会破坏其他数据。盲目地进行查找/替换可能会影响文件的其他部分。

回答

更改后的问题的解决方案基本上是相同的。

我们将必须使用regex where子句运行select查询。

有点像

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

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

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

回答

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

  • 该表只是作为varchar的单个列(alpha)。
mysql> desc t;

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| alpha | varchar(15) | YES  |     | NULL    |       | 
+-------+-------------+------+-----+---------+-------+
  • 添加记录
mysql> insert into t values('"1,000,000"');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;

+-------------+
| alpha       |
+-------------+
| "1,000,000" | 
+-------------+
  • 更新语句。
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文档,但看起来我无法找到并替换正则表达式。尽管我们可以像Eldila一样使用正则表达式进行查找,然后使用替代解决方案进行替换。

也要注意s /"(\ d +),(\ d +)" / $ 1 $ 2 /,因为如果数字多于一个逗号,例如" 1,000,000",我们会想做一个全局替换(在perl中为" s /// g")。但是,即使使用全局替换,替换也会从我们上次中断的地方开始(除非perl不同),并且会错过所有其他以逗号分隔的组。一种可能的解决方案是使第一个(\ d +)成为可选选项,例如s /(\ d +)?,(\ d +)/ $ 1 $ 2 / g,在这种情况下,我需要第二次查找并替换以剥离引号。

这是一些仅作用于字符串" 1,000,000"的正则表达式的红宝石示例,请注意,字符串内没有双引号,这只是数字本身的字符串。

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