我有一个这样的字符串:
"te_st"
并希望将 all underscores followed by a character
替换为此字符的大写版本。
来自"te_st"
- >找到(正则表达式:"_."
)--------替换为下一个字符(+大写字母("s"
- > "S"
)--------> "teSt"
来自"te_st"
--->到"teSt"
来自"_he_l_lo"
--->到"HeLLo"
来自"an_o_t_h_er_strin_g"
--->到"anOTHErStrinG"
...但是我无法真正使用Swift' NSRegularExpression
这样的小剪辑:
var result = "te_st" // result should be teSt
result = try! NSRegularExpression(pattern: "_*").stringByReplacingMatches(in: result, range: NSRange(0..<result.count), withTemplate: ("$1".uppercased()))
答案 0 :(得分:1)
这是使用NSRegularExpression的一个实现。我使用组匹配来获取_之后的字符并将其大写并替换字符串。
from airflow import configuration
def slack_failed_task(context):
link = '<{base_url}/admin/airflow/log?dag_id={dag_id}&task_id={task_id}&execution_date={execution_date}|logs>'.format(
base_url=configuration.get('webserver', 'BASE_URL'),
dag_id=context['dag'].dag_id,
task_id=context['task_instance'].task_id,
execution_date=context['ts'])) # equal to context['execution_date'].isoformat())
failed_alert = SlackAPIPostOperator(
task_id='slack_failed',
channel="#mychannel",
token="...",
text=':red_circle: Failure on: ' +
str(context['dag']) +
'\nRun ID: ' + str(context['run_id']) +
'\nTask: ' + str(context['task_instance']) +
'\nSee ' + link + ' to debug')
return failed_alert.execute(context=context)
这是另一个不使用正则表达式的人。我为方法做了扩展,也可以重用。
func capitalizeLetterAfterUnderscore(string: String) -> String {
var capitalizedString = string
guard let regularExpression = try? NSRegularExpression(pattern: "_(.)") else {
return capitalizedString
}
let matches = regularExpression.matches(in: string,
options: .reportCompletion,
range: NSMakeRange(0, string.count))
for match in matches {
let groupRange = match.range(at: 1)
let index = groupRange.location
let characterIndex = string.index(string.startIndex,
offsetBy: index)
let range = characterIndex ... characterIndex
let capitalizedCharacter = String(capitalizedString[characterIndex]).capitalized
capitalizedString = capitalizedString.replacingCharacters(in: range,
with: capitalizedCharacter)
}
capitalizedString = capitalizedString.replacingOccurrences(of: "_", with: "")
return capitalizedString
}
capitalizeLetterAfterUnderscore(string: "an_o_t_h_er_strin_g") // anOTHErStrinG
答案 1 :(得分:1)
没有常规语法将匹配转换为大写。您发布的代码正在尝试将字符串$1
转换为大写,当然只是$1
。它不会尝试在运行时转换$1
匹配所代表的值。
这是另一种使用正则表达式查找_
后跟小写字母的方法。这些被枚举并替换为大写字母。
extension String {
func toCamelCase() -> String {
let expr = try! NSRegularExpression(pattern: "_([a-z])")
var res = self
for match in expr.matches(in: self, range: NSRange(0..<res.count)).reversed() {
let range = Range(match.range, in: self)!
let letterRange = Range(match.range(at: 1), in: self)!
res.replaceSubrange(range, with: self[letterRange].uppercased())
}
return res
}
}
print("te_st".toCamelCase())
print("_he_l_lo".toCamelCase())
print("an_o_t_h_er_strin_g".toCamelCase())
输出:
测试
你好
anOTHErStrinG
答案 2 :(得分:0)
您可以使用带有range(of:, options:, range:)
选项的字符串.regularExpression
方法来匹配"_[a-z]"
的出现次数,并将范围内的索引处的字符替换为相反顺序的子范围。下限大写:
let string = "an_o_t_h_er_strin_g"
let regex = "_[a-z]"
var start = string.startIndex
var ranges:[Range<String.Index>] = []
while let range = string.range(of: regex, options: .regularExpression, range: start..<string.endIndex) {
start = range.upperBound
ranges.append(range)
}
var finalString = string
for range in ranges.reversed() {
finalString.replaceSubrange(range, with: String(string[string.index(after: range.lowerBound)]).uppercased())
}
print(finalString) // "anOTHErStrinG\n"
答案 3 :(得分:0)
问题是它将字符串“$ 1”转换为大写字母(不出所料,只改为“$ 1”)并使用“$ 1”作为模板。如果你想使用正则表达式,你必须自己枚举匹配。
另一种方法是将字符串分割为_
个字符,并将每个子字符串的第一个字符(第一个字符除外)大写,并使用reduce
将其重新连接在一起:
let input = "te_st"
let output = input.components(separatedBy: "_").enumerated().reduce("") { $0 + ($1.0 == 0 ? $1.1 : $1.1.uppercasedFirst()) }
或者,如果你的目标不是像大多数正则表达式一样编写代码,我们可以使它更清晰:
let output = input
.components(separatedBy: "_")
.enumerated()
.reduce("") { result, current in
if current.offset == 0 {
return current.element // because you don’t want the first component capitalized
} else {
return result + current.element.uppercasedFirst()
}
}
导致:
测试
注意,使用此扩展名来大写第一个字符:
extension String {
func uppercasedFirst(with locale: Locale? = nil) -> String {
guard count > 0 else { return self }
return String(self[startIndex]).uppercased(with: locale) + self[index(after: startIndex)...]
}
}
答案 4 :(得分:0)
如果您希望使用NSRegularExpression
进行某种动态转换,则可以继承NSRegularExpression
并覆盖replacementString(for:in:offset:template:)
:
class ToCamelRegularExpression: NSRegularExpression {
override func replacementString(for result: NSTextCheckingResult, in string: String, offset: Int, template templ: String) -> String {
if let range = Range(result.range(at: 1), in: string) {
return string[range].uppercased()
} else {
return super.replacementString(for: result, in: string, offset: 0, template: templ)
}
}
}
func toCamelCase(_ input: String) -> String { //Make this a String extension if you prefer...
let regex = try! ToCamelRegularExpression(pattern: "_(.)")
return regex.stringByReplacingMatches(in: input, options: [], range: NSRange(0..<input.utf16.count), withTemplate: "$1")
}
print(toCamelCase("te_st")) //-> teSt
print(toCamelCase("_he_l_lo")) //-> HeLLo
print(toCamelCase("an_o_t_h_er_strin_g")) //-> anOTHErStrinG