4 votos

AppleScript: ¿Cómo extraer una sección de una cadena (basada en caracteres definidos)?

Ejemplo:

set theText to "I ate an apple at 11:54 pm without the skin."

Me gustaría theTime sea una cadena que contenga el texto: 11:54

Por lo tanto, me gustaría que el delimitador del elemento de texto de apertura fuera at_ y el delimitador del elemento de texto de cierre debe ser _pm o _am dependiendo del periodo que exista en la cadena. (Nota - Cada instancia de un guión bajo en este post está destinada a representar un espacio porque soy incapaz de representar un espacio en el formato de código de Stack Exchange).

El contenido de theText variará mucho. Por ejemplo, podría ser:

set theText to "I ate two navel oranges at 6:30 am with a glass of water."

Pero el formato de tiempo siempre será constante. La hora siempre irá precedida de una "arroba" y esa "arroba" será siempre la primera instancia de una "arroba" en la cadena. Del mismo modo, la hora irá necesariamente seguida de "am" o "pm".

0 votos

He actualizado mi respuesta original para incluir un espacio antes de y después de los tres separadores de campo (delimitadores) " at ", " am " y " pm " ya que tiene más sentido hacerlo y no un solo espacio como se escribió originalmente.

0 votos

He vuelto a actualizar mi respuesta para mostrar cómo una sola línea de regular AppleScript código hace lo que las 8 líneas de puro AppleScript código hace en la otra respuesta.

0 votos

Bien, gracias. Sin embargo, me he dado cuenta de que, en realidad, prefiero tu solución original porque es más restrictiva, ya que responde exactamente a mi pregunta original con una interpretación literal (como has señalado). En general, me gusta hacer la menor cantidad de suposiciones posibles cuando escribo código, para ser conservador. Aunque no sea común o esperado, los dos puntos podrían existir antes del tiempo en theText cadena, lo que desorientaría un método basado en dos puntos para obtener theTime .

6voto

Seif Puntos 121

Puedes hacerlo con AppleScript puro, aunque el método del shell script presentado anteriormente es muy bonito:

set theText to "I ate an apple at 11:54 pm without the skin."
set the_colon_location to offset of ":" in theText
-- now we know where the colon is.
-- The Time is going to be on either side of it.
set the_starting_point to the_colon_location - 2
set the_ending_point to the_colon_location + 5
set the_time_string to characters the_starting_point thru the_ending_point of theText as string
-- in case the hour is not two digits, the first character will be a space
if character 1 of the_time_string is " " then
    set the_time_string to characters 2 thru -1 of the_time_string as string
end if
return the_time_string

0 votos

Siempre es bueno saber cómo hacer lo mismo de diferentes maneras, pero cuando set theTime to do shell script "awk 'match($0,/[0-9]{1,2}:[0-5][0-9]/) {print substr($0,RSTART,RLENGTH)}'<<<" & quoted form of theText produce los mismos resultados en una línea de regular AppleScript código que toma 8 líneas de su puro AppleScript código para hacer, no creo que use su método. Sin embargo, lo he añadido a mi archivo de fragmentos de código para tener un ejemplo del flujo lógico, por si encuentro una razón de peso para utilizarlo sobre un awk solución.

4 votos

Totalmente entendido. Sin embargo, mi respuesta no pretendía competir en velocidad o en número de líneas. Se trataba de que fuera legible y comprensible para el mayor número de personas posible. Me quito el sombrero ante el uso de expresiones regulares en la otra solución.

3voto

user3439894 Puntos 5883

Ejecutando el siguiente AppleScript código en el Editor de AppleScript:

set theText to "I ate an apple at 11:54 pm without the skin."
set theTime to do shell script "awk -F ' at | am | pm ' '{print $2}'<<<" & quoted form of theText
log "The time was: " & theTime

set theText to "I ate two navel oranges at 6:30 am with a glass of water."
set theTime to do shell script "awk -F ' at | am | pm ' '{print $2}'<<<" & quoted form of theText
log "The time was: " & theTime

Produce la siguiente salida en el registro de eventos del editor de AppleScript:

tell current application
    do shell script "awk -F ' at | am | pm ' '{print $2}'<<<'I ate an apple at 11:54 pm without the skin.'"
        --> "11:54"
    (*The time was: 11:54*)
    do shell script "awk -F ' at | am | pm ' '{print $2}'<<<'I ate two navel oranges at 6:30 am with a glass of water.'"
        --> "6:30"
    (*The time was: 6:30*)
end tell

En los ejemplos anteriores he definido el separadores de campo (delimitadores) en awk utilizando el -F opción como ' at | am | pm ' que equivale a " at ", " am " y " pm " e imprime '{print $2}' lo que hay entre el separadores de campo .

Nota: El uso del log comando no es necesario para la codificación de la respuesta y se utiliza sólo para mostrar lo que el valor de theTime contiene para la salida del registro de eventos aparte de lo que se muestra después de --> que es el resultado como normalmente se muestra en el registro de eventos.


Actualización: Escribí mi respuesta original basándome en una interpretación literal, en el sentido de que al decir " Por lo tanto, me gustaría que el delimitador del elemento de texto de apertura fuera `aty el delimitador del elemento de texto de cierre debe ser_pmoam` ", lo que se quería era utilizar literalmente esos como delimitadores. Sin embargo, ya que una solución diferente utilizando puro AppleScript código en una respuesta separada, permítame presentar un AppleScript de una línea código que hace lo mismo que las 8 líneas de puro AppleScript código y centrándose en la colon pero como parte de un RegEx representación del tiempo en horas y minutos.

set theTime to do shell script "awk 'match($0,/[0-9]{1,2}:[0-5][0-9]/) {print substr($0,RSTART,RLENGTH)}'<<<" & quoted form of theText

Ejecutando el siguiente AppleScript código en el Editor de AppleScript:

set theText to "I ate an apple at 11:54 pm without the skin."
set theTime to do shell script "awk 'match($0,/[0-9]{1,2}:[0-5][0-9]/) {print substr($0,RSTART,RLENGTH)}'<<<" & quoted form of theText

set theText to "I ate two navel oranges at 6:30 am with a glass of water."
set theTime to do shell script "awk 'match($0,/[0-9]{1,2}:[0-5][0-9]/) {print substr($0,RSTART,RLENGTH)}'<<<" & quoted form of theText

Produce la siguiente salida en el registro de eventos del editor de AppleScript:

tell current application
    do shell script "awk 'match($0,/[0-9]{1,2}:[0-5][0-9]/) {print substr($0,RSTART,RLENGTH)}'<<<'I ate an apple at 11:54 pm without the skin.'"
            --> "11:54"
    do shell script "awk 'match($0,/[0-9]{1,2}:[0-5][0-9]/) {print substr($0,RSTART,RLENGTH)}'<<<'I ate two navel oranges at 6:30 am with a glass of water.'"
            --> "6:30"
end tell

Como puede ver, tanto si hay uno o dos números precediendo a los dos puntos, el RegEx coincide y el awk programa devuelve la coincidencia deseada, siendo la hora.

Personalmente, elegiría usar este método en particular sobre mi respuesta original, ya que es un método mejor dadas las circunstancias, y o sobre el puro AppleScript código ya que no puedo justificar el escribir 8 líneas de puro AppleScript código cuando una sola línea de regular AppleScript código produce los mismos resultados que las 8 líneas.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X