我试图根据SAS中的关键字提取回车的部分字符串,例如。
Str="started manually 23:56:22
Skipped: obtain name
Completed: verify dob
Skipped: ask again
Skipped: verify address
Completed: verify country
Stopped manually 23:58:55"
我想根据Skipped
或Completed
提取部分内容。
因此,如果我要求Skipped,我会想要最终结果,包括回车:
Obtain name
Ask again
Verify address
我在想我需要循环查找跳过的每个实例。我尝试过SCAN,FIND,INDEX,SUBSTR的不同变体。
之前我已经提取了子字符串,但只有当字符串在字符/单词位置上保持一致时。 这个字符串非常大。可以使用不同的开始和结束措辞来存在任何跳过或已完成的数量。 我在SASeg工作。
答案 0 :(得分:1)
这里的基本想法是使用CALL SCAN
迭代字符串的单词,然后根据结果做任何你想做的事。
我在这里使用'|'
作为单词分隔符,因为很难让回车进入编辑器,但如果它真的是CR,则使用'0A'x
作为单词分隔符。
data have;
Str="started manually 23:56:22|Skipped: obtain name|Completed: verify dob|Skipped: ask again|Skipped: verify address|Completed: verify country|Stopped manually 23:58:55";
length str_els1-str_els10 $40;
array str_els[10] $;
_pos=0;
_count=1;
_length=0;
do _count = 1 by 1 until (_pos le 0);
call scan(str,_count,_pos,_length,'|');
if _pos>0 then str_els[_count] = substr(str,_pos,_length);
end;
run;
你可能想要做的不仅仅是把它放在一个数组中,但我想从这里你可以弄清楚剩下的。另一个:
的扫描可能是起点。
答案 1 :(得分:0)
我不知道如何使用SAS,但有一个建议可能是:
"/><Data type="
:_
_
(blank
为" value="
!)
这会产生类似
的东西started manually 23" value="56" value="22"/>
<Data type="Skipped" value="obtain name"/>
<Data type="Completed" value="verify dob"/>
<Data type="Skipped" value="ask again"/>
<Data type="Skipped" value="verify address "/>
<Data type="Completed" value="verify country"/>
<Data type="Stopped manually 23" value="58" value="55
将第一行替换为<root>
,将最后一行替换为</root>
,然后
<root>
<Data type="Skipped" value="obtain name"/>
<Data type="Completed" value="verify dob"/>
<Data type="Skipped" value="ask again"/>
<Data type="Skipped" value="verify address "/>
<Data type="Completed" value="verify country"/>
</root>
现在使用XPath
/root/Data[@type="Skipped"]
由于我不知道如何在SAS中使用XPath读取XML,我正在搜索并发现: POSITION()-function in PATH-element of XML-map works in XML Mapper, but not in SAS-code
希望这会有所帮助......
答案 2 :(得分:0)
好吧,不知道你在用什么语言,但是在C#中我会使用LINQ或者将字符串拆分成数组,如
public class ToggleBehavior : Behavior<View>
{
readonly TapGestureRecognizer tapRecognizer;
public ToggleBehavior()
{
tapRecognizer = new TapGestureRecognizer
{
Command = new Command(() => this.IsToggled = !this.IsToggled)
};
}
public static readonly BindableProperty IsToggledProperty = BindableProperty.Create<ToggleBehavior, bool>(tb => tb.IsToggled, false);
public bool IsToggled
{
set { SetValue(IsToggledProperty, value); }
get { return (bool)GetValue(IsToggledProperty); }
}
protected override void OnAttachedTo(View bindable)
{
base.OnAttachedTo(bindable);
bindable.GestureRecognizers.Add(this.tapRecognizer);
}
protected override void OnDetachingFrom(View bindable)
{
base.OnDetachingFrom(bindable);
bindable.GestureRecognizers.Remove(this.tapRecognizer);
}
protected override void OnAttachedTo(BindableObject bindable)
{
base.OnAttachedTo(bindable);
this.BindingContext = bindable.BindingContext;
bindable.BindingContextChanged += Bindable_BindingContextChanged;
}
protected override void OnDetachingFrom(BindableObject bindable)
{
base.OnDetachingFrom(bindable);
this.BindingContext = null;
bindable.BindingContextChanged -= Bindable_BindingContextChanged;
}
void Bindable_BindingContextChanged(object sender, EventArgs e)
{
var bobject = sender as BindableObject;
this.BindingContext = bobject?.BindingContext;
}
}
然后你可以遍历数组并单独找到各个单词,并在找到单词后返回接下来的2个索引。以下代码输出:
var myarray=str.Split(' ');
我确信Linq的答案会更加优雅......
在SQL中,不确定......
答案 3 :(得分:0)
你没有提到你是否想要这些摘录作为记录,所以这是我的简单方法:
您可以使用byte(10)
来模拟线路返回。
data a(keep=record str);
length str $200.;
str="started manually 23:56:22" || byte(10) ||
"Skipped: obtain name" || byte(10) ||
"Completed: verify dob" || byte(10) ||
"Skipped: ask again" || byte(10) ||
"Skipped: verify address" || byte(10) ||
"Completed: verify country" || byte(10) ||
"Stopped manually 23:58:55";
do i=1 by 1 while(scan(str,i,byte(10)) ^=' ');
new=scan(str,i,byte(10));
if index(new,"Skipped")>=1 or index(new,"Completed")>=1 then
record = scan(new,-1,":");
else
record = '';
if length(record)>1 then output;
end;
run;