解析一列的字符串并填充另一列你好,
我有一个包含 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 的样子。 谢谢你的协助。