解析一列的字符串並填充另一列你好,
我有一個包含 ProductName 的表,我想生成 OUTPUT 列。OUTPUT 列是 ProductID 與 Serial# 的串聯。 如何準確解析 Serial# 並創建 OUTPUT 列?
序列號示例:
- 07-08_13 表示序列號 07、08、13
- 09-12 表示序列號 09、10、11、12
- 01-03_05-08 表示序列號 01、02、03、05、06、07、08
- 01_04_05-08 表示序列號 01、04、05、06、07、08
- 09_11_13_14 表示序列號 09,11,13,14

| 產品名稱 | 輸出 |
| AABBCC_07-08_13 | AABBCC-07 |
| AABBCC_07-08_13 | AABBCC-08 |
| AABBCC_07-08_13 | AABBCC-13 |
| AABBCC_09-12 | AABBCC-09 |
| AABBCC_09-12 | AABBCC-10 |
| AABBCC_09-12 | AABBCC-11 |
| AABBCC_09-12 | AABBCC-12 |
| EEFFGG_02 | EEFFGG-02 |
| HHIIJJ_01-07 | HHIIJJ-01 |
| HHIIJJ_01-07 | HHIIJJ-02 |
| HHIIJJ_01-07 | HHIIJJ-03 |
| HHIIJJ_01-07 | HHIIJJ-04 |
| HHIIJJ_01-07 | HHIIJJ-05 |
| HHIIJJ_01-07 | HHIIJJ-06 |
| HHIIJJ_01-07 | HHIIJJ-07 |
| KKLLLMM_01-03_05-08 | KKLLLMM-01 |
| KKLLLMM_01-03_05-08 | KKLLLMM-02 |
| KKLLLMM_01-03_05-08 | KKLLLMM-03 |
| KKLLLMM_01-03_05-08 | KKLLLMM-05 |
| KKLLLMM_01-03_05-08 | KKLLLMM-06 |
| KKLLLMM_01-03_05-08 | KKLLLMM-07 |
| KKLLLMM_01-03_05-08 | KKLLLMM-08 |
| NNOOPP_01_04_05-08 | NNOOPP-01 |
| NNOOPP_01_04_05-08 | NNOOPP-04 |
| NNOOPP_01_04_05-08 | NNOOPP-05 |
| NNOOPP_01_04_05-08 | NNOOPP-06 |
| NNOOPP_01_04_05-08 | NNOOPP-07 |
| NNOOPP_01_04_05-08 | NNOOPP-08 |
| QQRRSS_09_11_13_14 | QQRRSS_09 |
| QQRRSS_09_11_13_14 | QQRSS_11 |
| QQRRSS_09_11_13_14 | QQRSS_13 |
| QQRRSS_09_11_13_14 | QQRRSS_14 |
數據表腳本編寫回复:解析一列的字符串並填充另一列很可能您可以使用 Lag 編寫一個公式來執行此操作(或使用 JSL 編寫腳本),但您也可以嘗試以交互方式執行此操作,但這需要很多步驟:
1. 選擇產品名稱列
2. 轉到 Cols/Utilities/Text To 列並使用 - 和 _ 作為分隔符

3. 轉到 Tables and Stack 並將除第一列之外的所有其他內容添加到 Stack Columns 選擇


5. 移除標籤欄
6. 選擇左邊的兩列並轉到行/行選擇/選擇重複行並刪除這些行

7. 選擇一個空值的單元格,然後選擇 Select Matching Cells 並刪除那些行
8. 現在選擇兩個列並右鍵單擊列標題並創建公式

9. 打開剛剛創建的公式並將 , 更改為 _

10.重命名和刪除列/公式
11.如果你需要ProductName 那裡,如果您沒有像我一樣在第一步中不小心刪除它,您應該能夠將其保留在那裡

如果您必須擁有 - 或 _ 取決於序列號,您很可能可以在連接公式中處理它
編輯:我更準確地檢查了這個問題,這比我在這裡展示的要復雜一些。 您必須為某些序列號添加計算,因為它們位於數字之間。 此解決方案在那些中不起作用,因為刪除重複項時將刪除某些行。
回复:解析一列的字符串並填充另一列你好@cchueng ,
有幾種方法。 有些是腳本基礎(尋找某人的回復和示例),或者您可以使用連續輪次的文本到列(示例在這裡找到)已解決:如何將一列中的文本拆分為多列? - JMP 用戶社區)然後,您可以通過選擇所需的列來連接它們,然後在右鍵單擊所選列之一後使用列公式或使用“新建公式列”選項。 尋找 concat 的 Character 選項。列公式更靈活,並為您提供了很多選項,請參閱有關此主題的幫助 (在 JMP 中創建公式)
我希望這能給你一些指導。
最好的事物,
回复:解析一列的字符串並填充另一列@jthi ,
你打敗了我。
你的解釋更詳細,也是我想到的。
回复:解析一列的字符串並填充另一列哦,你的權利。 - 被解釋為一個範圍,_ 被解釋為項目的真正分隔符
回复:解析一列的字符串並填充另一列謝謝,但我更喜歡 jsl 而不是交互式分隔符。 您的方法沒有解決串行 # 09-12. 它應該輸出如下所示的行。 不僅僅是 AABBCC-09 和 AABBCC-12。 “-”表示“到”表示範圍。 所以 09-12 表示 09、10、11、12。
| AABBCC_09-12 | AABBCC-09 |
| AABBCC_09-12 | AABBCC-10 |
| AABBCC_09-12 | AABBCC-11 |
| AABBCC_09-12 | AABBCC-12 |
回复:解析一列的字符串並填充另一列好的,這可能會奏效。 由於使用了 For Each 需要 JMP16(對於其他版本可以用 For 替換。 這是一個腳本化的解決方案,幾乎沒有註釋,並且需要特定的起始表才能工作(需要 OUTPUT 列)。
Names Default To Here(1);
dt = New Table("Untitled 4993",
Add Rows(32),
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14"}
)
),
New Column("OUTPUT",
Character(16),
"Nominal",
Set Values({"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""})
)
);
Summarize(dt, uniqProd = by(:ProductName));
valList = {};
For Each({prod}, uniqProd,
prodPart = Word(1, prod, "_");
serialPart = Substr(prod, Contains(prod, "_") + 1); //remove start
possibleRanges = Words(serialPart, "_"); //if they contain -
For Each({val}, possibleRanges,
If(Contains(val, "-"), //range
rangeVals = Words(val, "-");
For Each({val1}, Index(Num(rangeVals[1]), Num(rangeVals[2])),
valToAdd = Substr("0", Length(Char(val1))) || Char(val1);
Insert Into(valList, prodPart || "-" || valToAdd)
);
,
Insert Into(valList, prodPart || "-" || Substr("0", Length(Char(val))) || Char(val))
)
);
);
dt[0,"OUTPUT"] = valList;想知道是否可以使用 JMP 自己的模式匹配“輕鬆”完成這樣的事情@Craige_Hales
回复:解析一列的字符串並填充另一列嗨,克里斯,
我有一個腳本可以解決一些 ProductName 的問題,有時會錯誤地解析。 您能否查看並添加代碼以解決目前無法使用的產品名稱?
將適用於以下示例:
EEFFGG_02
HHIIJJ_01-07
KKLLLMM_01-03_05-08
不適用於以下示例:
AABBCC_07-08_13
NNOOPP_01_04_05-08
QQRRSS_09_11_13_14
dt=current data table();
(dt << New Column( "ProductID", Character )) << Set Selected;
(dt << New Column( "OUTPUT", Character )) << Set Selected;
//Parse string in ProductName column
For Each Row(
dt,
//Assign the ProductID value
:ProductID = Word( 1, :ProductName, "_-" ); //"_"
//If the ProductName changes, capture the start and end
If( :ProductName != Lag( :ProductName, 1 ),
start = Num( Word( 2, :ProductName, "_-" ) );
end = Num( Word( 3, :ProductName, "_-" ) );
);
//Assign the OUTPUT value
:OUTPUT = :ProductID || "-" || Repeat( "0", 2 - Length( Char( start ) ) ) || Char( start );
//After end value & there is an _, set start to value after _
If( start == end & Contains( :ProductName, "_"),
start = Num( Word(-2, :ProductName, "_-" ) ),
start++);
);
回复:解析一列的字符串並填充另一列你好,
感謝您的腳本,但我的表實際上是動態的。 每天,我都會從具有不同日期範圍的數據庫中提取此表,並且會出現不同的 ProductName 集。 所以它並不總是 32 行。 你的腳本幾乎可以工作,但你能解決數組大小嗎? 謝謝。
回复:解析一列的字符串並填充另一列這應該相當容易。 提取的數據中的行數是否與序列號一樣多?
回复:解析一列的字符串並填充另一列你好,
是的,行數與序列號數相匹配。
回复:解析一列的字符串並填充另一列如果是這樣的話,它應該已經能夠處理它了。 我做了一些小的修改(如果缺少,則創建 OUTPUT 列)。 目前它確實依賴於數據表按 ProductNames 排序的事實,這可能會在某些時候導致問題,或者您可以確保輸入表已排序(最簡單的解決方案)。
您應該能夠使用 For Each 部分,甚至可以在沒有數據表的情況下使用,只要您有名為 uniqProd 且具有 ProductNames 的列表變量。 之後只是弄清楚如何向數據表添加值。
Names Default To Here(1);
//Test table
/*
dt = New Table("Untitled 4993",
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14"}
)
)
);
*/
dt = Current Data Table();
Summarize(dt, uniqProd = by(:ProductName));
valList = {};
For Each({prod}, uniqProd, //loop for each ProductName
prodPart = Word(1, prod, "_");
serialPart = Substr(prod, Contains(prod, "_") + 1); //remove start
possibleRanges = Words(serialPart, "_"); //if they contain -
For Each({val}, possibleRanges, //Loop for serialnumber inside the ProductName
If(Contains(val, "-"), //range
rangeVals = Words(val, "-");
For Each({val1}, Index(Num(rangeVals[1]), Num(rangeVals[2])),
valToAdd = Substr("0", Length(Char(val1))) || Char(val1);
Insert Into(valList, prodPart || "-" || valToAdd)
);
,
Insert Into(valList, prodPart || "-" || Substr("0", Length(Char(val))) || Char(val))
)
);
);
//if starting table doesn't have OUTPUT column create it
If(!Contains(dt << Get Column Names("String"), "OUTPUT"),
dt << New Column("OUTPUT", Character, "Nominal");
);
//dt[0,"OUTPUT"] = valList; subscripting, maybe a bit more difficult to understand
dt:OUTPUT << Set Values(valList);
他們的腳本試圖做的簡化版本:
1.腳本獲取ProductName列中的所有唯一值
2. 腳本在 For Each 循環的兩部分中的每一個上循環
3. 第一個循環遍歷唯一值並將它們拆分為 Product 和 number 部分
4. 然後序列號部分再次循環以將其拆分為單個值。 這些單個值與 Product 部分連接,然後將字符串插入到 valList 列表中(這 4. 並不像我在這裡解釋的那麼簡單)。
5. 兩個循環完成後,您應該有一個列表,其中包含所有可能的序列號。 產品部分將按字母順序排列。
6. 如果存在此列表,則將其添加到 OUTPUT,如果不存在,則首先創建它。
回复:解析一列的字符串並填充另一列嗨,
如果我的 ProductName 是字符和數字的混合,您的腳本將不起作用。 我附上了一張桌子。 這就是我的大部分 productName 的樣子。 謝謝你的協助。