質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

3回答

7416閲覧

正規表現で"特定の文字で終わらない"行の検索について

jagabee72

総合スコア11

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2018/07/12 07:59

お世話になっております。
正規表現についての質問です。

末尾が特定の文字列で終わらない、といった条件で処理を行いたいのですが、どのような方法があるでしょうか。
いろいろ調べてパターンを試したのですが、やりたいことを実現する方法がわかりませんでした。

背景として、とあるDBからデータをcsv出力し、データの集計を行いたいのですが、
一番後ろのカラムのデータが長すぎると、csv出力した際に途中で改行されて出力されてしまいます。

例)
yyyy.mm.dd,abc,111,xxxxx
yyyy.mm.dd,def,222,xxxxxxxx
yyyy.mm.dd,ghi,333,xxxxxxxxxxx
xxx
yyyy.mm.dd,jkl,444,xxxxx

 ↑上記の例で、3レコード目が途中で改行され、4行目にきてしまっている

これが数件なら手で直すのですが、70万レコードぐらいあり、手で直すには少々つらい状況です。
末尾は必ず決まった文字が入る仕様ですので、末尾がその文字でなかった場合、改行コードを削除するように
置換処理を考えております。
※現状はsakuraのキーマクロで無理やり処理していますが、置換などできれいに処理したいと考えています

お手数ですが、よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mather

2018/07/12 08:57

「一番後ろのカラムのデータが長すぎると、csv出力した際に途中で改行されて出力されてしまいます。」こちらを修正できるならそれが一番いいと思うんですが…なにか事情があるんですよね。
KojiDoi

2018/07/12 11:49

linuxでやりたいということならそういうことは最初から書いておいてほしかったですね。正規表現にもいくつかバージョンがあり、一部の機能はツールによってサポートされていたりいなかったりします。
guest

回答3

0

「末尾がその文字でなかった場合、改行コードを」ということですが、その決まった文字が行の途中に出てこないという保証はあるのでしょうか。その保証なしにこのような置換を試みると、とりこぼしが出る可能性がありますよね。

例を見る限り、当該データは日付で始まることになっているように見受けられます。「先頭が日付ではない行」があった場合はそれを前の行につなぐという作戦の方がベターのように思いました。

しかし、筋論からいいますと、不適切な改行を後で削除するのではなく、「一番後ろのカラムのデータが長すぎると、csv出力した際に途中で改行されて出力されてしまう」腐った仕様をどうにかして、変な改行が最初から入らないように算段すべきと思います。

追記:
sakuraエディタなるものは知らなかったのでコードを提示しないでいたのですが、実際にはlinuxでやりたかったということですので、perlにて「先頭が日付ではない行」があった場合はそれを前の行につなぐという作戦」を書いてみました。ワンライナーでできます。日付のパターンの部分はもちろん実態に応じて書き換えてください。

perl -pe 'chomp; ($.>1 and /^yyyy.mm.dd/) and print "\n"; END{print "\n"}' input.csv

投稿2018/07/12 08:51

編集2018/07/12 11:59
KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jagabee72

2018/07/12 10:57

ご返信ありがとうございます。 決まった文字が行の途中に出てこないか、については、実は決まった文字は厳密には"文字列"であり、 行の途中には出てこないことが保証されております。 なお、以降のご指摘については仰る通りだと思います。 しかしながら、csv出力元のソフトは私が作ったものではなく、改修ができないものでございます。 そのため、本質問をさせて頂きました。 「「先頭が日付ではない行」があった場合はそれを前の行につなぐという作戦」についても 考えてみたのですが、置換で検索対象の前の文字を消すという方法がわからず、断念致しました。
think49

2018/07/12 11:22

> 「先頭が日付ではない行」があった場合はそれを前の行につなぐという作戦の方がベターのように思いました。 私もこの作戦が良いと思います。 To: jagabee72 さん > 考えてみたのですが、置換で検索対象の前の文字を消すという方法がわからず、断念致しました。 改行コードは検索対象なのですから、「検索対象の前」を探す必要はありませんよね。 検索: \n(?!yyyy.mm.dd) 置換: (空文字)
jagabee72

2018/07/13 03:03

>KojiDoiさま 追記ありがとうございます。 また、コードのご提示についても大変助かります。 頂いた内容にて試してみたいと思います。 >think49さま ありがとうございます。 仰る通り、ちょっと頭が固かったようです。 ご提案頂いた内容について試させて頂きます。 お二方、誠にありがとうございます。 すぐにでも試したいところですが、諸事情により本日は試せないので、後日試行させて頂きます。 本当に助かりました。
guest

0

ベストアンサー

csvで改行されている、ということは「対象以外の文字」+「改行コード」を検索し、該当行の「改行コード」を削除できればOKですかね。

※現状はsakuraのキーマクロで

↑sakureエディタを使用している、という事なので、正規表現での一括置換で終わりじゃないですかね。

検索対象:
「([^x])\r\n」

変換後:
「$1」

※改行文字は「CRLF」を想定して書いています。「LF」のみの場合はうまいこと対応してください。

投稿2018/07/12 08:34

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jagabee72

2018/07/12 11:00

ご返信ありがとうございます。 sakuraは苦肉の策でしたので、実際はLinux上で処理したい内容になります。 頂いたご回答を参考に、「%s/([^x])\n/\1/g」の置換でうまくいきました。 大変助かりました。
guest

0

ある文字以外 は、[^x] ですから、[^x]$ でうまくいきませんかね。

投稿2018/07/12 08:13

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jagabee72

2018/07/12 11:01

ご返信ありがとうございます。 文字列の否定を「^(?!x)」の方法でしか考えてなく、式が複雑化していましたが、 ご提示いただいた式がとてもヒントになりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問