「CSV/TSVでアクティブ列選択」の版間の差分
ナビゲーションに移動
検索に移動
編集の要約なし |
編集の要約なし |
||
| 2行目: | 2行目: | ||
このマクロは、CSVファイル内でアクティブな列を選択するためのものです。現在のカーソル位置を基準に、対応する列を自動的に全て選択します。 | このマクロは、CSVファイル内でアクティブな列を選択するためのものです。現在のカーソル位置を基準に、対応する列を自動的に全て選択します。 | ||
ダブルクォーテーション | |||
== 注意事項 == | == 注意事項 == | ||
| 19行目: | 21行目: | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
#title = "CSV/TSV でアクティブ列選択" | #title = "CSV/TSV でアクティブ列選択" | ||
BeginUndoGroup(); | |||
// フィールドのダブルクォーテーション囲みを考慮して列選択するかどうかのデフォルト値 | |||
// 考慮ありだと、ダブルクォーテーション内のデリミタや改行込みで列選択します。 | |||
// true: 考慮あり / false: 考慮なし | |||
var CONSIDER_DOUBLE_QUOTE_DEFAULT = true; | |||
// メニューID | |||
var CSV_ID = 1; | var CSV_ID = 1; | ||
var TSV_ID = 2; | var TSV_ID = 2; | ||
var CONSIDER_DOUBLE_QUOTE_ID = 3; | |||
// ダブルクォーテーションを考慮するかどうかの一時変更用 | |||
var considerDoubleQuote = CONSIDER_DOUBLE_QUOTE_DEFAULT; | |||
var DELIMITER_LIST = {} | |||
DELIMITER_LIST[CSV_ID] = "," | |||
DELIMITER_LIST[TSV_ID] = "\t" | |||
var console = { | |||
log: function (str) { | |||
outputBar.Writeln("---"); | |||
outputBar.Writeln(str); | |||
} | |||
}; | |||
var doc = document; | var doc = document; | ||
| 30行目: | 54行目: | ||
function main() { | function main() { | ||
// 現在の列位置を取得 | // 現在の列位置を取得 | ||
var | var actPos = sel.GetActivePos(); | ||
while (true) { | |||
// CSVかTSVかコンテキストメニューで指定 | |||
var menu = createContextMenu(); | |||
menuTrack = menu.Track(0); | |||
// メニュー選択がキャンセルされた場合は終了 | |||
if (menuTrack === 0) return; | |||
// ダブルクォーテーションを考慮するかどうかの設定 | |||
if (menuTrack === CONSIDER_DOUBLE_QUOTE_ID) { | |||
considerDoubleQuote = !considerDoubleQuote; | |||
continue; | |||
} | |||
break; | |||
} | |||
var delimiter = ""; | |||
switch (menuTrack) { | |||
case CSV_ID: | |||
delimiter = DELIMITER_LIST[CSV_ID]; | |||
if ( | break; | ||
case TSV_ID: | |||
delimiter = DELIMITER_LIST[TSV_ID]; | |||
break; | |||
} | |||
if (delimiter === "") { | |||
throw new Error("Delimiter is not set."); | |||
} | |||
var | var text = doc.Text; | ||
var | var startEndRangeList = null; | ||
if ( | if (considerDoubleQuote) { | ||
// | // カーソル位置がダブルクォーテーション囲みかどうかチェック | ||
var doubleQuoteStartPosition = getDoubleQuoteStartPosition(text, actPos, delimiter); | |||
if (doubleQuoteStartPosition != -1) { | |||
var | actPos = doubleQuoteStartPosition; | ||
if ( | |||
} | } | ||
// カーソル位置のフィールド番号を取得 | |||
var cursorFieldCount = getCursorFieldNumber(text, actPos, delimiter); | |||
// 各行のフィールド範囲を取得 | |||
startEndRangeList = getStartEndRangeList(text, cursorFieldCount, delimiter); | |||
} else { | } else { | ||
// | // カーソル位置のフィールド番号を取得 | ||
// | var cursorFieldCount = getCursorFieldNumberWithoutDoubleQuote(text, actPos, delimiter); | ||
// 各行のフィールド範囲を取得 | |||
startEndRangeList = getStartEndRangeListWithoutDoubleQuote(text, cursorFieldCount, delimiter); | |||
} | |||
// 各行のフィールド範囲を選択 | |||
// HACK: カーソル位置のフィールド範囲を最後に選択するため、カーソル位置のフィールド範囲を一時的に保持 | |||
var rangeWithCursor = null; | |||
for (var i = 0; i < startEndRangeList.length; i++) { | |||
var startEnd = startEndRangeList[i]; | |||
if (startEnd.startPos <= actPos && actPos <= startEnd.endPos) { | |||
rangeWithCursor = startEnd; | |||
continue; | |||
} | } | ||
sel.AddPos(startEnd.startPos, startEnd.endPos); | |||
} | |||
if (rangeWithCursor != null) { | |||
sel.AddPos(rangeWithCursor.startPos, rangeWithCursor.endPos); | |||
} | } | ||
} | } | ||
| 83行目: | 121行目: | ||
menu.Add("CSV でアクティブ列選択 (&C)", CSV_ID); | menu.Add("CSV でアクティブ列選択 (&C)", CSV_ID); | ||
menu.Add("TSV でアクティブ列選択 (&T)", TSV_ID); | menu.Add("TSV でアクティブ列選択 (&T)", TSV_ID); | ||
menu.Add("---", 0, meMenuSeparator); | |||
var t = "ダブルクォーテーション囲み考慮"; | |||
if (considerDoubleQuote) { | |||
menu.Add(t, CONSIDER_DOUBLE_QUOTE_ID, meMenuChecked); | |||
} else { | |||
menu.Add(t, CONSIDER_DOUBLE_QUOTE_ID); | |||
} | |||
return menu; | return menu; | ||
} | |||
/** | |||
* テキスト内の指定位置からダブルクォーテーションで囲まれた範囲の開始位置を取得します。 | |||
* | |||
* @param {string} text - 対象のテキスト。 | |||
* @param {number} actPos - 現在の位置(0から始まるインデックス)。 | |||
* @param {string} delimiter - 区切り文字(カンマやタブなど)。 | |||
* @returns {number} ダブルクォーテーションで囲まれた範囲の開始位置。囲まれていない場合は -1 を返します。 | |||
*/ | |||
function getDoubleQuoteStartPosition(text, actPos, delimiter) { | |||
for (var i = actPos; i >= 0; i--) { | |||
var checkString = text.charAt(i - 1) + text.charAt(i) | |||
// ダブルクォーテーション範囲閉じ位置に到達したので終了 | |||
if (actPos != i && (checkString === '"' + delimiter || checkString === '"\n')) { | |||
return -1; | |||
} | |||
// ダブルクォーテーション範囲始まり位置を発見したらその位置を返す | |||
if (checkString === delimiter + '"' || checkString === '"') { | |||
return i; | |||
} | |||
} | |||
return -1; | |||
} | |||
/** | |||
* カーソル位置のフィールド番号を取得します。 | |||
* | |||
* @param {string} text - テキスト全体の文字列。 | |||
* @param {number} actPos - カーソルの現在位置。 | |||
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。 | |||
* @returns {number} カーソル位置のフィールド番号。 | |||
*/ | |||
function getCursorFieldNumber(text, actPos, delimiter) { | |||
if (actPos == 0) { | |||
return 1; | |||
} | |||
var inDoubleQuote = false; | |||
var fieldCount = 1; | |||
for (var i = actPos - 1; i >= 0; i--) { | |||
if (text.charAt(i) === delimiter) { | |||
var checkString1 = text.charAt(i) + text.charAt(i + 1) | |||
var checkString2 = text.charAt(i - 1) + text.charAt(i) | |||
// ダブルクォーテーション範囲から抜ける | |||
if (inDoubleQuote && checkString1 === delimiter + '"') { | |||
inDoubleQuote = false; | |||
} | |||
// ダブルクォーテーション範囲内のデリミタはカウントしない | |||
if (!inDoubleQuote) { | |||
fieldCount++; | |||
} | |||
// ダブルクォーテーション範囲に入る | |||
if (checkString2 === '"' + delimiter) { | |||
inDoubleQuote = true; | |||
} | |||
} else if (inDoubleQuote && text.charAt(i) === '"' && (text.charAt(i - 1) === '\n' || i === 0)) { | |||
break; | |||
} else if (text.charAt(i) === '\n' && !inDoubleQuote) { | |||
break; | |||
} | |||
} | |||
return fieldCount; | |||
} | |||
/** | |||
* カーソル位置のフィールド番号を取得します。(ダブルクォーテーションを考慮しない) | |||
* | |||
* @param {string} text - テキスト全体の文字列。 | |||
* @param {number} actPos - カーソルの現在位置。 | |||
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。 | |||
* @returns {number} カーソル位置のフィールド番号。 | |||
*/ | |||
function getCursorFieldNumberWithoutDoubleQuote(text, actPos, delimiter) { | |||
if (actPos == 0) { | |||
return 1; | |||
} | |||
var fieldCount = 1; | |||
for (var i = actPos - 1; i >= 0; i--) { | |||
if (text.charAt(i) === delimiter) { | |||
fieldCount++; | |||
} else if (text.charAt(i) === '\n') { | |||
break; | |||
} | |||
} | |||
return fieldCount; | |||
} | |||
/** | |||
* テキスト内の指定されたフィールドの開始位置と終了位置のリストを取得します。 | |||
* | |||
* @param {string} text - 処理対象のテキスト。 | |||
* @param {number} cursorFieldCount - 開始位置と終了位置を取得するフィールドの番号(1から始まる)。 | |||
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。 | |||
* @returns {Array<{startPos: number, endPos: number}>} 指定されたフィールドの開始位置と終了位置のオブジェクトのリスト。 | |||
*/ | |||
function getStartEndRangeList(text, cursorFieldCount, delimiter) { | |||
var startEndRange = null; | |||
var startEndRangeList = []; | |||
var fieldCount = 1; | |||
var inDoubleQuote = false; | |||
var addStartEndRange = function (startEndRange) { | |||
if (startEndRange.startPos != startEndRange.endPos) { | |||
startEndRangeList.push(startEndRange); | |||
} | |||
} | |||
for (var i = 0; i < text.length; i++) { | |||
// 選択範囲の開始位置・終了位置を設定 | |||
if (startEndRange == null && fieldCount === cursorFieldCount) { | |||
startEndRange = { startPos: i, endPos: i }; | |||
} else if (startEndRange != null && fieldCount === cursorFieldCount + 1) { | |||
startEndRange.endPos = i - 1; | |||
addStartEndRange(startEndRange); | |||
startEndRange = null; | |||
} | |||
var checkString1 = text.charAt(i - 1) + text.charAt(i); | |||
var checkString2 = text.charAt(i) + text.charAt(i + 1); | |||
if (text.charAt(i) === delimiter) { | |||
// ダブルクォーテーション範囲から抜ける | |||
if (inDoubleQuote && checkString1 === '"' + delimiter) { | |||
inDoubleQuote = false; | |||
} | |||
// ダブルクォーテーション範囲内のデリミタはカウントしない | |||
if (!inDoubleQuote) { | |||
fieldCount++; | |||
} | |||
// ダブルクォーテーション範囲に入る | |||
if (checkString2 === delimiter + '"') { | |||
inDoubleQuote = true; | |||
} | |||
} else if (inDoubleQuote && text.charAt(i) === '"' && (text.charAt(i + 1) === '\n' || text.charAt(i + 1) === '')) { | |||
inDoubleQuote = false; | |||
} else if (!inDoubleQuote && text.charAt(i) === '"' && (text.charAt(i - 1) === '\n' || i == 0)) { | |||
inDoubleQuote = true; | |||
} else if (!inDoubleQuote && text.charAt(i) === '\n') { | |||
fieldCount = 1; | |||
// 改行でフィールドがリセットされるため、終了位置を設定 | |||
if (startEndRange != null) { | |||
startEndRange.endPos = i; | |||
addStartEndRange(startEndRange); | |||
startEndRange = null; | |||
} | |||
} else if (i == text.length - 1 && startEndRange != null) { | |||
// テキストの最後の場合 | |||
startEndRange.endPos = i + 1; | |||
addStartEndRange(startEndRange); | |||
} | |||
} | |||
return startEndRangeList; | |||
} | |||
/** | |||
* テキスト内の指定されたフィールドの開始位置と終了位置のリストを取得します。(ダブルクォーテーションを考慮しない) | |||
* | |||
* @param {string} text - 処理対象のテキスト。 | |||
* @param {number} cursorFieldCount - 開始位置と終了位置を取得するフィールドの番号(1から始まる)。 | |||
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。 | |||
* @returns {Array<{startPos: number, endPos: number}>} 指定されたフィールドの開始位置と終了位置のオブジェクトのリスト。 | |||
*/ | |||
function getStartEndRangeListWithoutDoubleQuote(text, cursorFieldCount, delimiter) { | |||
var startEndRange = null; | |||
var startEndRangeList = []; | |||
var fieldCount = 1; | |||
var inDoubleQuote = false; | |||
var addStartEndRange = function (startEndRange) { | |||
if (startEndRange.startPos != startEndRange.endPos) { | |||
startEndRangeList.push(startEndRange); | |||
} | |||
} | |||
for (var i = 0; i < text.length; i++) { | |||
// 選択範囲の開始位置・終了位置を設定 | |||
if (startEndRange == null && fieldCount === cursorFieldCount) { | |||
startEndRange = { startPos: i, endPos: i }; | |||
} else if (startEndRange != null && fieldCount === cursorFieldCount + 1) { | |||
startEndRange.endPos = i - 1; | |||
addStartEndRange(startEndRange); | |||
startEndRange = null; | |||
} | |||
if (text.charAt(i) === delimiter) { | |||
fieldCount++; | |||
} else if (!inDoubleQuote && text.charAt(i) === '\n') { | |||
fieldCount = 1; | |||
// 改行でフィールドがリセットされるため、終了位置を設定 | |||
if (startEndRange != null) { | |||
startEndRange.endPos = i; | |||
addStartEndRange(startEndRange); | |||
startEndRange = null; | |||
} | |||
} else if (i == text.length - 1 && startEndRange != null) { | |||
// テキストの最後の場合 | |||
startEndRange.endPos = i + 1; | |||
addStartEndRange(startEndRange); | |||
} | |||
} | |||
return startEndRangeList; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
2024年12月28日 (土) 20:48時点における版
概要
このマクロは、CSVファイル内でアクティブな列を選択するためのものです。現在のカーソル位置を基準に、対応する列を自動的に全て選択します。
ダブルクォーテーション
注意事項
- Mery Ver 3.7.9 で動作確認しています。
使い方
- MeryでCSVファイルを開く
- 選択したい列にカーソルを移動させる
- このマクロを実行すると、カーソル位置に対応する列が全て選択される
ソースコード
※2024/12/27 現在、ダブルクォーテーション内のカンマでフィールドがずれる問題や動作が重くなる問題を確認しています。改善に向け修正中です。
#title = "CSV/TSV でアクティブ列選択"
BeginUndoGroup();
// フィールドのダブルクォーテーション囲みを考慮して列選択するかどうかのデフォルト値
// 考慮ありだと、ダブルクォーテーション内のデリミタや改行込みで列選択します。
// true: 考慮あり / false: 考慮なし
var CONSIDER_DOUBLE_QUOTE_DEFAULT = true;
// メニューID
var CSV_ID = 1;
var TSV_ID = 2;
var CONSIDER_DOUBLE_QUOTE_ID = 3;
// ダブルクォーテーションを考慮するかどうかの一時変更用
var considerDoubleQuote = CONSIDER_DOUBLE_QUOTE_DEFAULT;
var DELIMITER_LIST = {}
DELIMITER_LIST[CSV_ID] = ","
DELIMITER_LIST[TSV_ID] = "\t"
var console = {
log: function (str) {
outputBar.Writeln("---");
outputBar.Writeln(str);
}
};
var doc = document;
var sel = doc.selection;
main();
function main() {
// 現在の列位置を取得
var actPos = sel.GetActivePos();
while (true) {
// CSVかTSVかコンテキストメニューで指定
var menu = createContextMenu();
menuTrack = menu.Track(0);
// メニュー選択がキャンセルされた場合は終了
if (menuTrack === 0) return;
// ダブルクォーテーションを考慮するかどうかの設定
if (menuTrack === CONSIDER_DOUBLE_QUOTE_ID) {
considerDoubleQuote = !considerDoubleQuote;
continue;
}
break;
}
var delimiter = "";
switch (menuTrack) {
case CSV_ID:
delimiter = DELIMITER_LIST[CSV_ID];
break;
case TSV_ID:
delimiter = DELIMITER_LIST[TSV_ID];
break;
}
if (delimiter === "") {
throw new Error("Delimiter is not set.");
}
var text = doc.Text;
var startEndRangeList = null;
if (considerDoubleQuote) {
// カーソル位置がダブルクォーテーション囲みかどうかチェック
var doubleQuoteStartPosition = getDoubleQuoteStartPosition(text, actPos, delimiter);
if (doubleQuoteStartPosition != -1) {
actPos = doubleQuoteStartPosition;
}
// カーソル位置のフィールド番号を取得
var cursorFieldCount = getCursorFieldNumber(text, actPos, delimiter);
// 各行のフィールド範囲を取得
startEndRangeList = getStartEndRangeList(text, cursorFieldCount, delimiter);
} else {
// カーソル位置のフィールド番号を取得
var cursorFieldCount = getCursorFieldNumberWithoutDoubleQuote(text, actPos, delimiter);
// 各行のフィールド範囲を取得
startEndRangeList = getStartEndRangeListWithoutDoubleQuote(text, cursorFieldCount, delimiter);
}
// 各行のフィールド範囲を選択
// HACK: カーソル位置のフィールド範囲を最後に選択するため、カーソル位置のフィールド範囲を一時的に保持
var rangeWithCursor = null;
for (var i = 0; i < startEndRangeList.length; i++) {
var startEnd = startEndRangeList[i];
if (startEnd.startPos <= actPos && actPos <= startEnd.endPos) {
rangeWithCursor = startEnd;
continue;
}
sel.AddPos(startEnd.startPos, startEnd.endPos);
}
if (rangeWithCursor != null) {
sel.AddPos(rangeWithCursor.startPos, rangeWithCursor.endPos);
}
}
function createContextMenu() {
const menu = CreatePopupMenu();
menu.Add("CSV でアクティブ列選択 (&C)", CSV_ID);
menu.Add("TSV でアクティブ列選択 (&T)", TSV_ID);
menu.Add("---", 0, meMenuSeparator);
var t = "ダブルクォーテーション囲み考慮";
if (considerDoubleQuote) {
menu.Add(t, CONSIDER_DOUBLE_QUOTE_ID, meMenuChecked);
} else {
menu.Add(t, CONSIDER_DOUBLE_QUOTE_ID);
}
return menu;
}
/**
* テキスト内の指定位置からダブルクォーテーションで囲まれた範囲の開始位置を取得します。
*
* @param {string} text - 対象のテキスト。
* @param {number} actPos - 現在の位置(0から始まるインデックス)。
* @param {string} delimiter - 区切り文字(カンマやタブなど)。
* @returns {number} ダブルクォーテーションで囲まれた範囲の開始位置。囲まれていない場合は -1 を返します。
*/
function getDoubleQuoteStartPosition(text, actPos, delimiter) {
for (var i = actPos; i >= 0; i--) {
var checkString = text.charAt(i - 1) + text.charAt(i)
// ダブルクォーテーション範囲閉じ位置に到達したので終了
if (actPos != i && (checkString === '"' + delimiter || checkString === '"\n')) {
return -1;
}
// ダブルクォーテーション範囲始まり位置を発見したらその位置を返す
if (checkString === delimiter + '"' || checkString === '"') {
return i;
}
}
return -1;
}
/**
* カーソル位置のフィールド番号を取得します。
*
* @param {string} text - テキスト全体の文字列。
* @param {number} actPos - カーソルの現在位置。
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。
* @returns {number} カーソル位置のフィールド番号。
*/
function getCursorFieldNumber(text, actPos, delimiter) {
if (actPos == 0) {
return 1;
}
var inDoubleQuote = false;
var fieldCount = 1;
for (var i = actPos - 1; i >= 0; i--) {
if (text.charAt(i) === delimiter) {
var checkString1 = text.charAt(i) + text.charAt(i + 1)
var checkString2 = text.charAt(i - 1) + text.charAt(i)
// ダブルクォーテーション範囲から抜ける
if (inDoubleQuote && checkString1 === delimiter + '"') {
inDoubleQuote = false;
}
// ダブルクォーテーション範囲内のデリミタはカウントしない
if (!inDoubleQuote) {
fieldCount++;
}
// ダブルクォーテーション範囲に入る
if (checkString2 === '"' + delimiter) {
inDoubleQuote = true;
}
} else if (inDoubleQuote && text.charAt(i) === '"' && (text.charAt(i - 1) === '\n' || i === 0)) {
break;
} else if (text.charAt(i) === '\n' && !inDoubleQuote) {
break;
}
}
return fieldCount;
}
/**
* カーソル位置のフィールド番号を取得します。(ダブルクォーテーションを考慮しない)
*
* @param {string} text - テキスト全体の文字列。
* @param {number} actPos - カーソルの現在位置。
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。
* @returns {number} カーソル位置のフィールド番号。
*/
function getCursorFieldNumberWithoutDoubleQuote(text, actPos, delimiter) {
if (actPos == 0) {
return 1;
}
var fieldCount = 1;
for (var i = actPos - 1; i >= 0; i--) {
if (text.charAt(i) === delimiter) {
fieldCount++;
} else if (text.charAt(i) === '\n') {
break;
}
}
return fieldCount;
}
/**
* テキスト内の指定されたフィールドの開始位置と終了位置のリストを取得します。
*
* @param {string} text - 処理対象のテキスト。
* @param {number} cursorFieldCount - 開始位置と終了位置を取得するフィールドの番号(1から始まる)。
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。
* @returns {Array<{startPos: number, endPos: number}>} 指定されたフィールドの開始位置と終了位置のオブジェクトのリスト。
*/
function getStartEndRangeList(text, cursorFieldCount, delimiter) {
var startEndRange = null;
var startEndRangeList = [];
var fieldCount = 1;
var inDoubleQuote = false;
var addStartEndRange = function (startEndRange) {
if (startEndRange.startPos != startEndRange.endPos) {
startEndRangeList.push(startEndRange);
}
}
for (var i = 0; i < text.length; i++) {
// 選択範囲の開始位置・終了位置を設定
if (startEndRange == null && fieldCount === cursorFieldCount) {
startEndRange = { startPos: i, endPos: i };
} else if (startEndRange != null && fieldCount === cursorFieldCount + 1) {
startEndRange.endPos = i - 1;
addStartEndRange(startEndRange);
startEndRange = null;
}
var checkString1 = text.charAt(i - 1) + text.charAt(i);
var checkString2 = text.charAt(i) + text.charAt(i + 1);
if (text.charAt(i) === delimiter) {
// ダブルクォーテーション範囲から抜ける
if (inDoubleQuote && checkString1 === '"' + delimiter) {
inDoubleQuote = false;
}
// ダブルクォーテーション範囲内のデリミタはカウントしない
if (!inDoubleQuote) {
fieldCount++;
}
// ダブルクォーテーション範囲に入る
if (checkString2 === delimiter + '"') {
inDoubleQuote = true;
}
} else if (inDoubleQuote && text.charAt(i) === '"' && (text.charAt(i + 1) === '\n' || text.charAt(i + 1) === '')) {
inDoubleQuote = false;
} else if (!inDoubleQuote && text.charAt(i) === '"' && (text.charAt(i - 1) === '\n' || i == 0)) {
inDoubleQuote = true;
} else if (!inDoubleQuote && text.charAt(i) === '\n') {
fieldCount = 1;
// 改行でフィールドがリセットされるため、終了位置を設定
if (startEndRange != null) {
startEndRange.endPos = i;
addStartEndRange(startEndRange);
startEndRange = null;
}
} else if (i == text.length - 1 && startEndRange != null) {
// テキストの最後の場合
startEndRange.endPos = i + 1;
addStartEndRange(startEndRange);
}
}
return startEndRangeList;
}
/**
* テキスト内の指定されたフィールドの開始位置と終了位置のリストを取得します。(ダブルクォーテーションを考慮しない)
*
* @param {string} text - 処理対象のテキスト。
* @param {number} cursorFieldCount - 開始位置と終了位置を取得するフィールドの番号(1から始まる)。
* @param {string} delimiter - フィールドを区切るデリミタ(例: カンマ、タブ)。
* @returns {Array<{startPos: number, endPos: number}>} 指定されたフィールドの開始位置と終了位置のオブジェクトのリスト。
*/
function getStartEndRangeListWithoutDoubleQuote(text, cursorFieldCount, delimiter) {
var startEndRange = null;
var startEndRangeList = [];
var fieldCount = 1;
var inDoubleQuote = false;
var addStartEndRange = function (startEndRange) {
if (startEndRange.startPos != startEndRange.endPos) {
startEndRangeList.push(startEndRange);
}
}
for (var i = 0; i < text.length; i++) {
// 選択範囲の開始位置・終了位置を設定
if (startEndRange == null && fieldCount === cursorFieldCount) {
startEndRange = { startPos: i, endPos: i };
} else if (startEndRange != null && fieldCount === cursorFieldCount + 1) {
startEndRange.endPos = i - 1;
addStartEndRange(startEndRange);
startEndRange = null;
}
if (text.charAt(i) === delimiter) {
fieldCount++;
} else if (!inDoubleQuote && text.charAt(i) === '\n') {
fieldCount = 1;
// 改行でフィールドがリセットされるため、終了位置を設定
if (startEndRange != null) {
startEndRange.endPos = i;
addStartEndRange(startEndRange);
startEndRange = null;
}
} else if (i == text.length - 1 && startEndRange != null) {
// テキストの最後の場合
startEndRange.endPos = i + 1;
addStartEndRange(startEndRange);
}
}
return startEndRangeList;
}
スポンサーリンク