문제
다음에서 일부 데이터를 가져오고 있습니다. CSV
파일 및 다음보다 큰 숫자 1000
변신하다 1,100
등.
여기에서 따옴표와 쉼표를 모두 제거하여 int
필드?
편집하다:
데이터는 실제로 이미 MySQL 테이블에 있으므로 SQL을 사용하여 이를 수행할 수 있어야 합니다.혼란을 드려 죄송합니다.
해결책
정규식의 좋은 사례는 다음과 같습니다.가져오기 전(더 쉬움)이나 나중에 SQL 가져오기에서 해당 문자를 허용한 경우(거의 쉽지는 않음) 데이터에 대해 찾기 및 바꾸기를 실행할 수 있습니다.그러나 두 경우 모두 편집기, 스크립팅 언어, GUI 프로그램 등 찾기 및 바꾸기를 수행할 수 있는 방법이 많습니다.당신이 찾고 교체하고 싶어한다는 것을 기억하십시오 모두 나쁜 캐릭터 중.
쉼표와 따옴표(큰따옴표만 가정)를 찾는 일반적인 정규식은 다음과 같습니다. (블랙리스트)
/[,"]/
또는 미래에 변경될 수 있는 사항이 있는 경우 이 정규식은 숫자나 소수점을 제외한 모든 항목과 일치합니다. (화이트리스트)
/[^0-9\.]/
위의 사람들이 논의한 내용은 우리가 CSV 파일의 모든 데이터를 알 수 없다는 것입니다.CSV 파일의 모든 숫자에서 쉼표와 따옴표를 제거하려는 것 같습니다.그러나 CSV 파일에 다른 내용이 무엇인지 모르기 때문에 다른 데이터가 손상되지 않았는지 확인하고 싶습니다.맹목적으로 찾기/바꾸기를 수행하면 파일의 다른 부분에 영향을 줄 수 있습니다.
다른 팁
내 생각에는 데이터를 가져올 수 있었기 때문에 필드가 실제로 varchar 또는 일부 문자 필드인 것을 가져올 수 있었기 때문에 숫자 필드로 가져오는 것이 실패했을 수 있습니다.다음은 순수하게 MySQL, SQL 솔루션을 실행한 테스트 사례입니다.
테이블은 varchar인 단일 열(알파)입니다.
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 문서 그리고 정규식 찾기를 할 수 없을 것 같았어요 교체하고.당신이 할 수 있지만, 엘딜라, 찾기에는 정규식을 사용한 다음 바꾸기에는 대체 솔루션을 사용합니다.
또한 조심하세요 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+)/, '\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
조금 가지고 놀아야 할 수도 있지만 트릭을 수행해야 합니다.
사실 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
Daniel과 Eldila의 답변에는 한 가지 문제가 있습니다.전체 파일에서 모든 따옴표와 쉼표를 제거합니다.
이런 일을 해야 할 때 내가 보통 하는 일은 먼저 모든 구분 따옴표와 (보통) 세미콜론을 탭으로 바꾸는 것입니다.
- 찾다: ";"
- 바꾸다: \티
영향을 받는 값이 어느 열에 있는지 알고 있으므로 다른 검색을 수행하고 바꿉니다.
- 찾다: ^([ ]+) ([ ]+) ([0-9]+),([0-9]+)
- 바꾸다: \1 \2 \3\4
...쉼표가 있는 값은 세 번째 열에 있습니다.
줄의 시작 부분에서 시작하려면 "^"로 시작해야 합니다.그런 다음 그대로 두려는 열이 있는 만큼 자주 ([0-9]+) 를 반복합니다.
([0-9]+),([0-9]+)는 숫자, 쉼표, 다른 숫자가 있는 값을 검색합니다.
대체 문자열에서는 \1과 \2를 사용하여 편집된 줄의 값을 유지하고 (탭)로 구분합니다.그런 다음 \3\4(사이에 탭 없음)를 넣어 숫자의 두 구성요소를 쉼표 없이 서로 바로 뒤에 배치합니다.그 이후의 모든 값은 그대로 유지됩니다.
요소를 구분하기 위해 파일에 세미콜론이 있어야 하는 경우 계속해서 탭을 세미콜론으로 바꿀 수 있습니다.그러나 따옴표를 생략하는 경우 텍스트 값 자체에 세미콜론이 포함되어 있지 않은지 확인해야 합니다.이것이 바로 TAB을 열 구분 기호로 사용하는 것을 선호하는 이유입니다.
나는 보통 RegExp를 지원하는 일반 텍스트 편집기(EditPlus)에서 이 작업을 수행하지만 동일한 정규식은 모든 프로그래밍 언어에서 사용될 수 있습니다.